9

免責事項: Java で実行時にこれを生成できることを認識しています。これは、一部のコードのパフォーマンス テスト中に非常に特殊なケースで必要でした。私は別のアプローチを見つけたので、これは実用的なものよりも単なる好奇心です。

以下を静的フィールド、インスタンス フィールドとして試し、コンストラクター内で直接初期化しました。Eclipse が「コンストラクタ TestData() のコードが 65535 バイトの制限を超えています」または「静的イニシャライザのコードが 65535 バイトの制限を超えています」と通知するたびに。

10,000 個の整数があります。各 int が 4 バイト (32 ビット) の場合、それは 40,000 バイトではないでしょうか? 単に配列を構築するだけのデータに加えて、25,000 バイト以上のオーバーヘッドが実際にありますか?

データは、この小さな Python で生成されます。

#!/usr/bin/python

import random;
print "public final int[] RANDOM_INTEGERS = new int[] {";
for i in range(1,10000):
    print str(int(random.uniform(0,0x7fffffff))) + ",";
print "};";

ここに小さなサンプルがあります:

public final int[] RANDOM_INTEGERS = new int[] {
    963056418, 460816633, 1426956928, 1836901854, 334443802, 721185237, 488810483,
    1734703787, 1858674527, 112552804, 1467830977, 1533524842, 1140643114, 1452361499,
    716999590, 652029167, 1448309605, 1111915190, 1032718128, 1194366355, 112834025,
    419247979, 944166634, 205228045, 1920916263, 1102820742, 1504720637, 757008315,
    67604636, 1686232265, 597601176, 1090143513, 205960256, 1611222388, 1997832237,
    1429883982, 1693885243, 1987916675, 159802771, 1092244159, 1224816153, 1675311441,
    1873372604, 1787757434, 1347615328, 1868311855, 1401477617, 508641277, 1352501377,
    1442984254, 1468392589, 1059757519, 1898445041, 1368044543, 513517087, 99625132,
    1291863875, 654253390, 169170318, 2117466849, 1711924068, 564675178, 208741732,
    1095240821, 1993892374, 87422510, 1651783681, 1536657700, 1039420228, 674134447,
    1083424612, 2137469237, 1294104182, 964677542, 1506442822, 1521039575, 64073383,
    929517073, 206993014, 466196357, 1139633501, 1692533218, 1934476545, 2066226407,
    550646675, 624977767, 1494512072, 1230119126, 1956454185, 1321128794, 2099617717,
    //.... to 10,0000 instances
4

6 に答える 6

14

{1000001, 1000002, 1000003} で配列を初期化するためのバイトコードは次のとおりです。

 5  iconst_3
 6  newarray int [10]
 8  dup
 9  iconst_0
10  ldc <Integer 1000001> [12]
12  iastore
13  dup
14  iconst_1
15  ldc <Integer 1000002> [13]
17  iastore
18  dup
19  iconst_2
20  ldc <Integer 1000003> [14]
22  iastore
23  putfield net.jstuber.test.TestArrayInitializingConstructor.data : int[] [15]

したがって、この小さな配列では、各要素に 5 バイトの Java バイトコードが必要です。より大きな配列の場合、配列インデックスと定数プールへのインデックスの両方がほとんどの要素に 3 バイトを使用するため、配列要素ごとに 8 バイトになります。したがって、10000 要素の場合、約 80kB のバイト コードを期待する必要があります。

大きな配列を 16 ビット インデックスで初期化するコードは次のようになります。

2016  dup
2017  sipush 298
2020  ldc_w <Integer 100298> [310]
2023  iastore
2024  dup
2025  sipush 299
2028  ldc_w <Integer 100299> [311]
于 2009-04-25T12:53:34.377 に答える
6

配列リテラルは、配列に値を入力するバイト コードに変換されるため、数値ごとにさらに数バイトが必要です。

そのデータを、クラスのロード時に静的初期化ブロックでロードするリソースに移動してみませんか? これは、 を使用して簡単に実行できますMyClass.class.getClassLoader().getResourceAsStream()。とにかく、これはそれが属する場所のようです。

または、利用可能な Java ツールを使用して、静的初期化ブロックでランダム値を作成することをお勧めします。また、反復可能な「乱数」が必要な場合は、Random毎回ランダムに選択された固定の数値をインスタンスにシードするだけです。

于 2009-04-25T12:28:03.580 に答える
3

整数の値に加えて、コンストラクターと初期化子には、整数を配列にロードするための JVM 命令が含まれている必要があります。

于 2009-04-25T12:19:52.803 に答える
1

はるかに単純で実用的な方法は、バイナリ形式またはテキストとして数値をファイルに保存することです。

この方法でどの Java が配列を初期化するのかはわかりませんが、大きな配列を効率的に初期化することはできません。

于 2009-04-25T15:28:32.943 に答える
0

文字単位のコードサイズは65535以上だと思います。10000個の整数が占めるメモリではありません。

于 2009-04-25T12:18:48.407 に答える
-5

これは、これらの int を英数字で表すために必要なメモリの量である可能性があると思います。この制限はコード自体に適用される可能性があると思うので、たとえば 1494512072 などの各 int は、int32 に使用される 4 バイトだけではなく、実際には 10 バイト (1 桁あたり 1 つ) を使用します。

于 2009-04-25T12:15:44.420 に答える