この問題の理由は、予想よりもはるかに興味深いものです。
次のコードを調べてください。7つのテストが含まれています。
結果は次のとおりです。
- 864-リテラル定数intと比較
- 866-intと比較
- 1358-ベクトルの長さと比較(サイズは固定)
- 1376-ベクトルの長さで計算(動的サイズ)
- 3159-オブジェクトメンバーと比較
- 3152-静的オブジェクトメンバーと比較
- 11855-配列の長さと比較
なぜ最後のものは他のものと比較してとても遅いと思いますか?配列が毎回長さを再計算するからではなく、それはばかげているでしょう。
これを読む:
lengthプロパティ:配列内の要素の数を指定する非負の整数。このプロパティは、新しい要素が配列に追加されると自動的に更新されます。配列要素に値を割り当てる場合(たとえば、my_array [index] = value)、indexが数値であり、index + 1がlengthプロパティよりも大きい場合、lengthプロパティはindex+1に更新されます。
理由は実装にあります
//Implementation
public function get length():uint
public function set length(value:uint):void
他の6つのテストでは、クラスの通常のパブリックメンバーを使用します。配列はgetter関数とsetter関数を使用して、長さの値を取得します。テストを詳しく説明し続けると、関数呼び出しに貴重な時間がかかることがわかります。より高いパフォーマンスが必要な場合は、インラインコードに依存する必要がある場合があります。それはほとんど毎回真実です。これは、プロセッサがコード内の別の領域に「ジャンプ」し、新しいスコープといくつかの追加の理由を作成する必要があるためです。
インライン化が関数呼び出しよりも高速であると見なされるのはなぜですか?
ベクトルの長さの実装を確認すると、配列(ゲッターおよびセッター)関数とは異なり、それが単なるパブリックメンバーであることがわかります。ゲッターとセッターは拡張性に優れています。クラスから継承することを決定した場合、セッターは値をチェックすることで特定のエラーを防ぐこともできます。スピードで公共施設に勝るものはありません。
package regression
{
import flash.display.Sprite;
import flash.utils.getTimer;
/**
* ...
* @author Arthur Wulf White
*/
public class Check_Loop_Speed_1 extends Sprite
{
//BIG_NUMBER == 100,000,000
public function Check_Loop_Speed_1()
{
var i : int = 0, j : int = 100000000, time : int = 0;
var vector: Vector.<Boolean> = new Vector.<Boolean>(100000000, true),
vect2 : Vector.<Boolean> = new Vector.<Boolean>(100000000),
obj : Object = new TestObject(),
arr : Array = new Array();
arr.length = 100000000;
//test 1
time = getTimer();
for (i = 0; i < 100000000; i++) { }
trace(getTimer() - time);
//test 2
time = getTimer();
for (i = 0; i < j; i++) { }
trace(getTimer() - time);
//test 3
time = getTimer();
for (i = 0; i < vector.length; i++) { }
trace(getTimer() - time);
//test 4
time = getTimer();
for (i = 0; i < vect2.length; i++) { }
trace(getTimer() - time);
//test 5
time = getTimer();
for (i = 0; i < obj.val; i++) { }
trace(getTimer() - time);
//test 6
time = getTimer();
for (i = 0; i < obj.val2; i++) { }
trace(getTimer() - time);
//test 7
time = getTimer();
for (i = 0; i < arr.length; i++) { }
trace(getTimer() - time);
}
}
}
class TestObject
{
public var val : uint = 100000000;
public const val2 : uint = 100000000;
}