[解決済み】 .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
2022-04-15 23:24:30
質問
ArrayListがあると仮定します。
ArrayList<MyClass> myList;
そして、toArrayを呼び出したいのですが、パフォーマンス上の理由で
MyClass[] arr = myList.toArray(new MyClass[myList.size()]);
以上
MyClass[] arr = myList.toArray(new MyClass[0]);
?
私は2番目のスタイルの方が冗長でないので好きです。また、コンパイラは空の配列が本当に作成されないようにすると思っていましたが、そうなのでしょうか?
もちろん、99%の場合はどっちでもいいのですが、通常のコードと最適化された内部ループの間で、一貫したスタイルを保ちたいので...。
どのように解決するのですか?
逆算すると、Hotspot 8での、最速のバージョンは。
MyClass[] arr = myList.toArray(new MyClass[0]);
jmhを使ったマイクロベンチマークを実行した結果とコードを以下に示しますが、空の配列を使ったバージョンが、サイズの決まった配列を使ったバージョンよりも常に優れていることがわかります。なお、正しいサイズの既存の配列を再利用できる場合は、結果が異なる可能性があります。
ベンチマーク結果(スコアはマイクロ秒単位、小さいほど良い)。
Benchmark (n) Mode Samples Score Error Units
c.a.p.SO29378922.preSize 1 avgt 30 0.025 ▒ 0.001 us/op
c.a.p.SO29378922.preSize 100 avgt 30 0.155 ▒ 0.004 us/op
c.a.p.SO29378922.preSize 1000 avgt 30 1.512 ▒ 0.031 us/op
c.a.p.SO29378922.preSize 5000 avgt 30 6.884 ▒ 0.130 us/op
c.a.p.SO29378922.preSize 10000 avgt 30 13.147 ▒ 0.199 us/op
c.a.p.SO29378922.preSize 100000 avgt 30 159.977 ▒ 5.292 us/op
c.a.p.SO29378922.resize 1 avgt 30 0.019 ▒ 0.000 us/op
c.a.p.SO29378922.resize 100 avgt 30 0.133 ▒ 0.003 us/op
c.a.p.SO29378922.resize 1000 avgt 30 1.075 ▒ 0.022 us/op
c.a.p.SO29378922.resize 5000 avgt 30 5.318 ▒ 0.121 us/op
c.a.p.SO29378922.resize 10000 avgt 30 10.652 ▒ 0.227 us/op
c.a.p.SO29378922.resize 100000 avgt 30 139.692 ▒ 8.957 us/op
参考までに、コードを。
@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
public class SO29378922 {
@Param({"1", "100", "1000", "5000", "10000", "100000"}) int n;
private final List<Integer> list = new ArrayList<>();
@Setup public void populateList() {
for (int i = 0; i < n; i++) list.add(0);
}
@Benchmark public Integer[] preSize() {
return list.toArray(new Integer[n]);
}
@Benchmark public Integer[] resize() {
return list.toArray(new Integer[0]);
}
}
同様の結果、詳細な分析、考察はブログ記事でご覧いただけます。 古代の知恵の配列 . 要約すると、JVMとJITコンパイラは、新しい正しいサイズの配列を安価に作成し初期化するためのいくつかの最適化を含んでおり、自分で配列を作成する場合はそれらの最適化を使用することはできないのです。
関連
-
をインスタンス化することができません。
-
スレッド "main" で例外発生 java.lang.ArrayIndexOutOfBoundsException: 4 at text.Division.main(Divisi
-
起動時にEclipseエラーが発生しました。起動中に内部エラーが発生しました。java.lang.NullPoin: "Javaツーリングの初期化 "中に内部エラーが発生しました。
-
[解決済み] Swift Betaのパフォーマンス:配列のソート
-
[解決済み] Typeから新しいオブジェクトのインスタンスを作成する方法
-
[解決済み] Javaで新しいListを作成する方法
-
[解決済み] LINQクエリでToList()とToArray()のどちらを呼び出すのが良いですか?
-
[解決済み] リストを新規に作成せずにセットをリストに変換する
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
-
[解決済み】モダンC++はタダで性能を手に入れられる?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
ファインバグタイプ
-
Eclipseで "XXXX "の解決策を(型に)解決することができない
-
Intellij IDEAのエラー「CreateProcess error=2, system could not find specified file」に対する完璧な解決策です。
-
Spring boot runs with Error creating bean with name 'entityManagerFactory' defined in class path resource
-
スレッド "main" で例外発生 java.lang.ArrayIndexOutOfBoundsException: 0 at One1.main(One1.java:3)
-
node js npm gruntインストール、elasticsearch-head 5.Xインストール
-
java -serverコマンドで「Error: no `server' JVM at ... jvm.dll」を解決する方法です。
-
[解決済み] Integerを含むArrayListをprimitive int配列に変換する方法は?
-
[解決済み】arrayList.toArray()でより具体的な型を返すようにする。
-
[解決済み] コレクションを配列に変換する最も簡単な方法とは?