一般に、位置番号システムで文字列を解釈するのは非常にコストがかかります。BigInteger コンストラクターは、基数が 2 の累乗である特殊なケースには最適化されていません。これは、少しテストすれば明らかです。
public static void main(String [] args) {
char[] digits = new char[200000];
Arrays.fill(digits, '1');
String s = new String(digits);
StopWatch watch = new StopWatch("new BigInteger");
BigInteger bigInt = new BigInteger(s, 2);
watch.done();
watch = new StopWatch("toByteArray");
byte[] data = bigInt.toByteArray();
watch.done();
}
200k 桁の場合、次のように表示されます。
new BigInteger took 0.772188085
toByteArray took 0.001747708
100k 桁の場合、次のように表示されます。
new BigInteger took 0.200759594
toByteArray took 0.000973587
明らかに、new BigInteger は O(n^2) アルゴリズムを採用しています。
2 進数を変換することを知っていれば、変換を単純化できます。
static byte[] convert(String binaryString) {
// assumes binaryString.length() is a multiple of 8
byte[] bytes = new byte[binaryString.length() / 8];
byte data = 0;
for (int i = 0; i < bytes.length; i++) {
int minIndex = i * 8;
int maxIndex = (i + 1) * 8;
for (int j = minIndex; j < maxIndex; j++) {
data <<= 1;
data |= binaryString.charAt(j) - '0';
}
bytes[i] = data;
}
return bytes;
}
これを 100 万文字の char 配列で実行すると、次のようになります。
new BigInteger took 19.086559046
toByteArray took 0.003656331
convert took 0.009119036
上記のコードはテストされていません。自己責任で使用してください:-)
非常に大きな数値の場合は、バイトが変換されたときに OutputStream に書き込むことをお勧めします。その場合は、BufferedOutputStream を使用する必要があります。