forked from: Array Performance Check
配列のパフォーマンスチェック.
@author kawakita
@version 0.1
メモリの計算はgcのタイミングによる気がします.
メモリ使用量がマイナスになるのはgcが起きるせいです.
オリジナルの比較検証では,forEachが遅いということでしたが,
基本型でしかチェックしていない為, 実用的な検証としては不十分かもしれません.
forEachの利点は実行時の型推論を押さえられることです.
/**
* Copyright 9re ( http://wonderfl.net/user/9re )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/aVHL
*/
// forked from kawakita's Array Performance Check
// forked from kawakita's Template for Performance Check
package {
import flash.display.MovieClip;
import flash.system.System;
import flash.events.Event;
/**
* 配列のパフォーマンスチェック.
* @author kawakita
* @version 0.1
*
* メモリの計算はgcのタイミングによる気がします.
* メモリ使用量がマイナスになるのはgcが起きるせいです.
*
* オリジナルの比較検証では,forEachが遅いということでしたが,
* 基本型でしかチェックしていない為, 実用的な検証としては不十分かもしれません.
* forEachの利点は実行時の型推論を押さえられることです.
*/
public class TestTemplate extends MovieClip{
//------- CONST ------------------------------------------------------------------------
//------- MEMBER -----------------------------------------------------------------------
private var _output:Output;
//------- PUBLIC -----------------------------------------------------------------------
/** コンストラクタ. */
public function TestTemplate() {
// init output;
_output = new Output();
_output.setSize( stage.stageWidth, stage.stageHeight );
stage.addEventListener(Event.RESIZE, function(e:Event):void {
_output.setSize( stage.stageWidth, stage.stageHeight );
});
addChild(_output);
_output.split(20);
// 配列アクセスへの検証.
var n:Number;
var len:int = 200000;
var arr:Array;
var vec:Vector.<Type>;
init();
n = 0;
_output.print("■ for でアクセス.");
test( function():void {
for ( var i:uint = 0; i < len; ++i ) {
n += arr[i].number;
}
} );
n = 0;
_output.print("\n■ while でアクセス.");
test( function():void {
var i:uint = 0;
while ( i < len ) {
n += arr[i].number;
++i;
}
} );
n = 0;
_output.print("\n■ for( key in arr ) でアクセス.");
test( function():void {
for( var key:* in arr ) {
n += arr[key].number;
}
} );
n = 0;
_output.print("\n■ forEach でアクセス.");
test( function():void {
arr.forEach(function (type:Type, index:int, a:Array):void {
n += type.number;
});
} );
n = 0;
_output.print("\n■ forとVector");
test( function():void {
for ( var i:uint = 0; i < len; ++i ) {
n += vec[i].number;
}
} );
n = 0;
_output.print("\n■ forEachとforEach");
test( function():void {
vec.forEach(function (type:Type, index:int, v:Vector.<Type>):void {
n += type.number;
});
} );
function init():void {
n = 0;
arr = [];
vec = new Vector.<Type>;
for (var i:int = 0; i < len; i++) {
arr[arr.length] = new Type(i);
vec.push(new Type(i));
}
}
}
/**
* 引数で与えられた関数を実行し、メモリ使用量と所要時間を調べます.
* @param testFunction
*/
public function test( testFunction:Function ):void {
var b4Mem:Number = System.totalMemory;
var now:Number = new Date().getTime();
testFunction();
_output.print({
"Memory" : ( System.totalMemory - b4Mem ) + " bytes",
"Time " : ( new Date().getTime() - now ) + " ms"
});
}
//------- PRIVATE ----------------------------------------------------------------------
//------- PROTECTED --------------------------------------------------------------------
//------- INTERNAL ---------------------------------------------------------------------
}
}
import flash.display.*;
class Type extends Sprite{
public var number:int;
public function Type(n:int) {
number = n;
}
}
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.text.*;
import flash.ui.Keyboard;
class Output extends MovieClip{
//------- MEMBER ----------------------------------------------------------------------
private var _width:Number;
private var _height:Number;
private var _totalHeight:Number;
private var _scrollY:Number;
private var _currentItem:DisplayObject;
private var _itemList:Array;
//------- PUBLIC ----------------------------------------------------------------------
/** コンストラクタ. */
public function Output():void {
_scrollY = 0;
_totalHeight = 0;
_currentItem = null;
_itemList = [];
addEventListener(Event.ADDED_TO_STAGE, _onAddedToStage );
}
/** 描画の横幅. */
override public function get width():Number { return super.width; }
override public function set width(value:Number):void {
if ( value == width ) return;
setSize( value, height );
}
/** 描画の縦幅. */
override public function get height():Number { return _totalHeight; }
override public function set height(value:Number):void {
if ( value == height ) return;
setSize( width, value );
}
/**
* 描画サイズを指定します.
* @param w
* @param h
*/
public function setSize( w:Number, h:Number ):void {
_width = w;
_height = h;
_updateAll();
}
/**
* 引数で渡した内容を出力します.
* @param value
*/
public function print( value:* ):void {
if( !_currentItem || !(_currentItem is TextField ) ){
_currentItem = _createTextField();
_itemList[_itemList.length] = addChild(_currentItem);
}
var tf:TextField = _currentItem as TextField;
tf.appendText( ( ( value is String ) ? value : _printObject( value ) ) + "\n" );
_updateY();
}
/**
* 分割のための処理を提供します.
*/
public function split( size:Number = 10, useLine:Boolean = true ):void {
_currentItem = new Split( size, useLine );
_currentItem.width = _width;
_itemList[_itemList.length] = addChild( _currentItem );
_updateY();
}
//------- PRIVATE ----------------------------------------------------------------------
/** 描画をすべて更新. */
private function _updateAll():void {
var len:uint = _itemList.length;
for (var i:uint = 0; i < len; i++){
_itemList[i].width = _width;
}
}
/** 高さのみ更新. */
private function _updateY():void {
var d:DisplayObject;
var bottom:Number = 0;
var len:uint = _itemList.length;
for (var i:uint = 0; i < len; i++) {
d = _itemList[i];
d.y = bottom;
bottom += d.height;
}
_totalHeight = bottom + 50;
}
/** オブジェクトを出力.*/
private function _printObject( obj:Object, tabLength:uint = 0 ):String {
// Create Tab.
var t:String = "";
while ( t.length < tabLength ) t += " ";
// Create Text.
var strArr:Array = [];
for ( var key:String in obj ) {
if ( obj[key] is String || obj[key] is Number ) {
strArr[strArr.length] = t + key + " : " + obj[key];
}else if ( obj[key] is Function ) {
strArr[strArr.length] = t + key + " : " + obj[key].toString();
}else {
var sChar:String, eChar:String;
if ( obj[key] is Array ) {
sChar = "["; eChar = "]";
}else {
sChar = "{"; eChar = "}";
}
strArr[strArr.length] = [
t + key + " : " + sChar,
_printObject( obj[key], tabLength + 2 ),
t + eChar
].join("\n");
}
}
// Return Created Text.
return strArr.join("\n");
}
/** TextField の 生成 */
private function _createTextField( format:TextFormat = null ):TextField {
var tf:TextField = new TextField();
tf.autoSize = TextFieldAutoSize.LEFT;
tf.defaultTextFormat = format || new TextFormat("_等幅");
tf.multiline = true;
tf.text = "";
tf.wordWrap = true;
tf.width = _width;
return tf;
}
private function _onAddedToStage(e:Event):void {
stage.addEventListener(KeyboardEvent.KEY_DOWN, _onKeyDown );
}
private function _onKeyDown(e:KeyboardEvent):void {
if ( e.keyCode == Keyboard.DOWN ) {
_scrollY += 20;
}else {
_scrollY -= 20;
}
_scrollY = Math.max( 0, Math.min( _totalHeight - _height, _scrollY ) );
scrollRect = new Rectangle( 0, _scrollY, _width, _height );
}
}
class Split extends MovieClip {
private static var _BMD:BitmapData;
private var _size:Number;
private var _useLine:Boolean;
/** コンストラクタ. */
public function Split( size:Number, useLine:Boolean ):void {
if ( !_BMD ) {
_BMD = new BitmapData( 2, 1 );
_BMD.setPixel32( 0, 0, 0xff000000 );
}
_size = size;
_useLine = useLine;
}
override public function get width():Number { return super.width; }
override public function set width(value:Number):void {
graphics.clear();
graphics.beginFill( 0xffffff, 0 );
graphics.drawRect( 0, 0, value, _size );
graphics.endFill();
if ( _useLine ) {
graphics.beginBitmapFill( _BMD );
graphics.drawRect( 0, Math.round( _size / 2 ), value, 1 );
graphics.endFill();
}
}
}