0

次のようなファイルに一連のビットを書き込んでいます。

//String to ByteArray
byte[] b = new BigInteger(encodedFile.toString(), 2).toByteArray();
//Writing
FileOutputStream fos = new FileOutputStream(fileName.concat(".file"),true);
fos.write(b);

100kb のファイルからのビット列では問題なく動作しますが、それよりも大きいと非常に遅くなります。

より大きなビット列でそれを行う最も効率的な方法は何ですか?

4

1 に答える 1

0

一般に、位置番号システムで文字列を解釈するのは非常にコストがかかります。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 を使用する必要があります。

于 2013-04-10T22:58:29.250 に答える