通常,在位置数字系统中解释字符串是非常昂贵的。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
显然,新的 BigInteger 采用了 O(n^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。