いつNewする?変数宣言時でしょ!
なんだか「今でしょ」みたいなタイトルですね。
結論から言うと「Newは変数宣言時にしましょう」というお話です。
オブジェクト変数やクラス変数を作成するには、Newキーワードを使いインスタンスを生成する必要があります。
このNewキーワードは、『変数を宣言したとき』または『オブジェクトを参照させるとき』に使用します。
次のサンプルをご覧ください。
基本的には2つのうちどちらかで処理を書くと思います。
さて、この2つの書き方は、どちらを書けば良いでしょうか?
性能の検証をしてみましょう。
今回はただ2つのパターンだけではつまらないので、さらに、Object宣言をしてからNewする方法についても併せて検証してみたいと思います。
検証用サンプルプログラム
今回は3つのパターンを用意しました。
1.変数宣言時にNew サンプルプログラム
2.変数宣言してからNew サンプルプログラム
3.Object宣言してからNew サンプルプログラム
検証
上記3つのパターンについての実行結果は次の通りです。
1,000,000回ループで検証しています。
回数 | 変数宣言時にNew | 変数宣言してからNew | Object宣言してからNew |
---|---|---|---|
1回目 | 0.153 | 0.709 | 0.698 |
2回目 | 0.151 | 0.707 | 0.700 |
3回目 | 0.152 | 0.708 | 0.698 |
4回目 | 0.152 | 0.706 | 0.699 |
5回目 | 0.152 | 0.705 | 0.701 |
6回目 | 0.153 | 0.707 | 0.700 |
7回目 | 0.154 | 0.706 | 0.698 |
8回目 | 0.153 | 0.705 | 0.699 |
9回目 | 0.152 | 0.705 | 0.700 |
10回目 | 0.153 | 0.707 | 0.702 |
平均 | 0.153 | 0.707 | 0.700 |
※単位は全て『秒』
結果は一目瞭然です。
変数宣言時にNewをする方法が圧倒的に早いことがわかります。
どうしてこんなに差がついてしまうのでしょうか?
実はその答えはMicrosoft Visual Basic のヘルプに書いてあります。
New 省略可能です。このキーワードを指定すると、オブジェクトを暗黙的に作成できます。オブジェクト変数を宣言するときにキーワード New を指定した場合は、オブジェクトを最初に参照したときにオブジェクトの新しいインスタンスが作成されるので、Set ステートメントを使ってオブジェクトへの参照を代入する必要はありません。
[ Microsoft Visual Basic のヘルプ - Dim ステートメントより引用 ]
変数宣言時にNewをしただけではインスタンスは作られず、そのオブジェクトに初めてアクセスしたときにインスタンスが作られる。と書いてあります。
ステップ実行で見てみるとわかります。以下画像をご覧ください。

つまり先ほどの検証では明らかに公平な検証を行っていないことになります。
これは意外と落とし穴です!なので、もう一度検証を行ってみましょう。
検証用サンプルプログラム 2回目
インスタンスを作るために、オブジェクトにアクセスをしてみましょう。
Newした後にCountを呼んでみます。
obj.Count
のところですね。
1.変数宣言時にNew サンプルプログラム (改良版)
2.変数宣言してからNew サンプルプログラム (改良版)
3.Object宣言してからNew サンプルプログラム (改良版)
検証 2回目
さて、2回目の検証では実行結果はどうなっているでしょうか?
結果は次の通りです。
回数 | 変数宣言時にNew | 変数宣言してからNew | Object宣言してからNew |
---|---|---|---|
1回目 | 0.773 | 0.732 | 3.064 |
2回目 | 0.728 | 0.730 | 3.062 |
3回目 | 0.726 | 0.732 | 3.068 |
4回目 | 0.726 | 0.730 | 3.063 |
5回目 | 0.725 | 0.730 | 3.072 |
6回目 | 0.727 | 0.730 | 3.073 |
7回目 | 0.727 | 0.735 | 3.068 |
8回目 | 0.727 | 0.731 | 3.065 |
9回目 | 0.728 | 0.734 | 3.089 |
10回目 | 0.727 | 0.731 | 3.066 |
平均 | 0.731 | 0.732 | 3.069 |
※単位は全て『秒』
変数宣言時にNewした場合と、変数宣言してからNewした場合とでは、処理速度に差は見られませんでした。
ということはインスタンスを生成する変数については、「変数を宣言する際に(どうせ必ずNewするのだから)Newと書いておく」か、「Newするタイミングを明記したいのでSetステートメントを使う」かのどちらか理由で使い分ければ良いのでしょう。
ちなみにObject宣言をした場合に処理速度が遅いのは、最初に作られる変数の領域と次に作られる変数の領域が異なるため、「変数を作り直す」という処理が実行されるためです。
「無駄にキャスト処理を行っている」と言えますね。
今回の検証では、実行速度についてもそうですが、インスタンスの生成タイミングについても大事なポイントがわかりました。
処理のタイミングで使用しているメモリを把握して、性能向上を図りたいものですね。