3

ArrayListたまにしか使用されないフィールドを持つクラスがいくつかあります。私は通常、これらのフィールドを次のように初期化します。

private List<Widget> widgets = new ArrayList<>();

オーバーロード コンストラクターを使用して初期容量を設定することについて理解しているので、これらのフィールドを次のように宣言する必要があるかどうか疑問に思っています。

private List<Widget> widgets = new ArrayList<>(0);

ジレンマは、リストを 0 で初期化すると、アイテムを 1 つでも追加するために常にリスト自体を再初期化する必要があることです。しかし、デフォルトのコンストラクターを使用すると、デフォルトの容量が 10 になり、未使用の容量でメモリを浪費しているアイテムがたくさん (そしてたくさんある可能性があります) ある可能性があります。

「どのくらいの頻度で」「どのくらいの数のアイテムを期待しているか」と質問する人もいると思いますが、私は本当に「ベスト プラクティス」のアプローチを探しています。すべてが等しい場合、時々使用されるリストで、(0)またはリストで初期化する必要がありますか?()

常にリストを初期化するのが私たちの部門のポリシーなので、単にリストをそのままにしておくことはできませんnull

4

6 に答える 6

5

時期尚早の最適化は諸悪の根源です。- D.クヌート。

これは、実際にはパフォーマンスにまったく影響を与えない一種の「パフォーマンスの問題」のようです。1 つには、これらの空のリストが実際に初期化されていることをどの程度確信していますか? 最近のほとんどのコンパイラは、オブジェクトが呼び出されることが確実にわかるまで、オブジェクトの初期化を遅らせているのではないかと思います。したがって、引数なしのコンストラクターを渡すと、リストに何かが追加されない限り、使用されることはほとんどありません。一方、引数が 0 のコンストラクターを使用すると、使用するすべてのコンストラクターのサイズを変更する必要があることが保証されます。

これらは、パフォーマンス最適化の 3 つの法則です。

  1. コンパイルされたコードが実際に何をしているかを知っている、またはコンパイラよりも優れた小さな最適化を行うことができると思い込まないでください。
  2. プロファイラーを使用してボトルネックがどこにあるかを突き止めずに最適化しないでください。知っていると思われる場合は、ルール番号 (1) を参照してください。
  3. アプリケーションにパフォーマンスの問題がない限り、気にしないでください。次に、ルール (2) を参照してください。

コンパイラを理解しているとまだ信じている場合は、次の質問を確認してください。並べ替えられた配列は、並べ替えられていない配列よりも処理が速いのはなぜですか?

于 2014-04-15T13:05:22.247 に答える
0

すでに述べたように、遅延初期化は、リストを初期化する (したがって初期サイズを選択する) 必要がある瞬間を延期することで役立ちます。

オブジェクトを null で初期化することを許可していない部門のポリシーが原因で遅延初期化ができない場合 (これについてはあまり意味がありません)、回避策として空のリストを次のように初期化することが考えられます。

List widget = new ArrayList<>(0)

実際にリストを操作する必要がある場合にのみ、新しいリスト オブジェクトを作成します。

widget = new ArrayList<>(someSize)

その時点で、リストが到達できる最大サイズ (または少なくともその桁数) を知ることができれば幸いです。

これは非常にばかげたトリックですが、あなたのポリシーに準拠しています。

于 2014-04-15T13:25:48.643 に答える