FlashLite2.0以降向けベンチマーク

FlashLite2.0以降向けベンチマークケータイは機種によって再生速度がどれくらい異なるのだろう? という疑問に対して、みんなでベンチマークとって比較すればいいんじゃね? というアプローチをしてみた。というかしています。現在進行中。
ここ数年以内に発売された機種を使っている人は、左のQRコードから、ベンチマークテストに参加すると良いと思う(*個人情報は取得していません)。結果は以下。

デフォルトでは日時順にソートしているので、ベンチマークをとった人はこのページをリロードすれば自分の結果を確認できます。
[kml_flashembed fversion=”9.0.0″ movie=”http://www.mztm.jp/wp/wp-content/uploads/2009/05/umhr_fldatagrid.swf” targetclass=”flashmovie” publishmethod=”static” width=”592″ height=”665″]

Get Adobe Flash player

[/kml_flashembed]

特に重要なのは以下
◆ベンチマーク部
TIME:大量の計算を行った時間(ミリ秒:小さいほど早い)
DW:ムービークリップアニメーションの時間(ミリ秒:小さいほど早い)
StageSize:Flash再生ステージサイズ(画面サイズscreenResolutionとは異なる)
◆Capabilities部
Device:端末名
Version:FlashPlayerのバージョン(FlashLiteも内部的にはPC向けと同期したバージョンナンバーになっていることがわかる)
FreeMemory:空きメモリ量(大きいほど余裕がある。この値が小さいと画像が赤くなりやすい、という噂)

↓20090526現在のベンチマーク結果logsファイル
http://www.mztm.jp/wp/wp-content/uploads/2009/05/logs.txt

↓ベンチマーク結果表示用swfのasファイル

/*


参考
・AS3でDataGridのソートを文字列から数値にする
http://ryow.net/blog/2008/08/24-013209.php
・DataGridのソートについて
http://www.flash-jp.com/modules/newbb/viewtopic.php?topic_id=1675&forum=11&post_id=9564#forumpost9564
・Capabilities - ActionScript 3.0 言語およびコンポーネントリファレンス
http://help.adobe.com/ja_JP/AS3LCR/Flash_10.0/flash/system/Capabilities.html

DIDについては値の特性がわからない。端末、simカードの特定の可能性を考えて、非表示にしている。
・Cisco Unified CallManager: Direct-Inward-Dial (DID)の概要
http://www.cisco.com/JP/support/public/mt/tac/100/1004007/did-and-callmanager.shtml
*/
package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.display.StageScaleMode;
	import fl.controls.DataGrid;

	public class Main extends Sprite{
		private var loadFiles_array:Array;
		private var MultiLoader:MultiLoaderClass;
		private var dataxmlURL:String = "http://mztm.heteml.jp/cake/logs/show";
		private var txt1:TextField;
		private var txt2:TextField;
		private var isSideBarMode:Boolean;
		
		public function Main(){
			stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = "TL";
			isSideBarMode = (stage.stageWidth < 300);
			
			if(!isSideBarMode){
				MakeUI.defaultTextFormat = new TextFormat("_sans", 14);
				txt1 = MakeUI.newTextField([0,400,stage.stageWidth/2,265],[["wordWrap",true],["backgroundColor",0xF0F0F0],["background",true]]);
				txt1.text = "・↑値のタイトルをクリックでソートが行われます。\n・測定値をクリックするとここに詳細が表示されます。";
				txt2 = MakeUI.newTextField([stage.stageWidth/2,400,stage.stageWidth/2,265],[["wordWrap",true],["backgroundColor",0xF0F0F0],["background",true]]);
			}
			
			MultiLoader = new MultiLoaderClass();
			loadFiles_array = MultiLoader.setLoad([dataxmlURL], onXMLComp);
		}
		private function onXMLComp(e:Array):void{
			var nameObj:Object = {AVD:"avHardwareDisable",ACC:"hasAccessibility",A:"hasAudio",AE:"hasAudioEncoder",EV:"hasEmbeddedVideo",IME:"hasIME",MP3:"hasMP3",PR:"hasPrinting",SB:"hasScreenBroadcast",SP:"hasScreenPlayback",SA:"hasStreamingAudio",SV:"hasStreamingVideo",TLS:"hasTLS",VE:"hasVideoEncoder",DEB:"isDebugger",L:"language",LFD:"localFileReadDisable",M:"manufacturer",ML:"maxLevelIDC",OS:"os",AR:"pixelAspectRatio",PT:"playerType",COL:"screenColor",DP:"screenDPI",R:"screenResolution",V:"Version",SS:"StageSize",D:"Device",FM:"FreeMemory",TIME:"TIME",VOL:"Volume"};
			
			var data_xml:XML = XML(loadFiles_array[0].data);
			var data_array:Array = new Array();
			var len:int = data_xml.log.length();
			for (var i:int = 0; i < len; i++) {
				var _length:int = data_xml.log[i].split("&").length;
				var _obj:Object = new Object();
				_obj["DATE"] = String(data_xml.log[i].@date).replace(/-/g,"");
				for (var j:int = 0; j < _length; j++) {
					var _array:Array = data_xml.log[i].split("&")[j].split("=");
					if(nameObj[_array[0]]){
						_array[0] = nameObj[_array[0]];
					}
					_obj[_array[0]] = _array[1];
				}
				data_array.push(_obj);
			}
			
			var columns_array:Array;
			var dg:DataGrid;
			if(isSideBarMode){
				columns_array = ["DATE","Device","Version","TIME"];
				dg = Create.newDataGrid([0,0,stage.stageWidth,stage.stageHeight],columns_array,data_array);
				dg.getColumnAt(2).width = 60;
				dg.getColumnAt(3).width = 40;
				dg.sortItemsOn("DATE", Array.DESCENDING);
				dg.columns[2].sortCompareFunction=sortNumberTime;
			}else{
				columns_array = ["DATE","Device","Version","FreeMemory","TIME","DW","StageSize"];
				dg = Create.newDataGrid([0,0,592,400],columns_array,data_array);
				dg.getColumnAt(0).width = 115;
				dg.getColumnAt(4).width = 60;
				dg.getColumnAt(5).width = 60;
				dg.getColumnAt(6).width = 70;
				dg.sortItemsOn("DATE", Array.DESCENDING);
				dg.columns[3].sortCompareFunction=sortNumberFM;
				dg.columns[4].sortCompareFunction=sortNumberTime;
				dg.columns[5].sortCompareFunction=sortNumberDw;
				dg.addEventListener("change",gridItemSelected);
				addChild(txt1);
				addChild(txt2);
			}
			addChild(dg);
			
			function sortNumberFM(obj1: Object, obj2: Object):int {
				var value1:Number = Number(obj1.FreeMemory);
				var value2:Number = Number(obj2.FreeMemory);
				if (value1 < value2) {
					return -1;
				} else if (value1 > value2) {
					return 1;
				} else {
					return 0;
				}
			}
			function sortNumberTime(obj1: Object, obj2: Object):int {
				var value1:Number = Number(obj1.TIME);
				var value2:Number = Number(obj2.TIME);
				if (value1 < value2) {
					return -1;
				} else if (value1 > value2) {
					return 1;
				} else {
					return 0;
				}
			}
			function sortNumberDw(obj1: Object, obj2: Object):int {
				var value1:Number = Number(obj1.DW);
				var value2:Number = Number(obj2.DW);
				if (value1 < value2) {
					return -1;
				} else if (value1 > value2) {
					return 1;
				} else {
					return 0;
				}
			}			
		}
		private function gridItemSelected(e:Event):void {
			var _obj:Object = e.target.selectedItem; 
			var _array:Array = new Array();
			for (var _str:String in _obj) {
				if(_str == "" || _str == "DID"){continue};
				_array.push(_str+":"+_obj[_str]+"\n");
			}
			txt1.text = txt2.text = "";
			for (var i:int= 0; i<_array.length; i++){
				if(_array.length/2>i){
					txt1.appendText(_array[i]);
				}else{
					txt2.appendText(_array[i]);
				}
			}
		}
	}
}

class Utill extends Sprite {
	public static function shuffle(_n:int):Array {
		var _array:Array = new Array(); 
		for (var i:int= 0; i<_n; i++){ 
			_array[i] = Math.random(); 
		} 
		return _array.sort(Array.RETURNINDEXEDARRAY); 
	} 
}


import fl.controls.DataGrid;
import flash.events.Event;
class Create extends Sprite{
	public static function newDataGrid(x_y_w_h:Array = null,columns_array:Array = null,item_array:Array = null):DataGrid {
		var dg:DataGrid = new DataGrid();
		dg.move(x_y_w_h[0],x_y_w_h[1]);
		dg.setSize(x_y_w_h[2],x_y_w_h[3]);
		dg.columns = columns_array;
		for (var i:int= 0; i<item_array.length; i++){
			dg.addItem(item_array[i]);
		}
		dg.minColumnWidth = dg.width/14;
		return dg;
	}
}
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.display.Sprite;
import flash.display.Shape;
import flash.display.BitmapData;
import flash.display.Bitmap;
class MakeUI{
    public static var defaultTextFormat:TextFormat = new TextFormat();
    public static function newShape(x_y_w_h_sh:Array = null,property:Array=null,graphics:Array=null):Shape{
        var i:int;
        var sh:Shape;
        if(x_y_w_h_sh && x_y_w_h_sh[4]){
            sh = x_y_w_h_sh[4];
        }else{
            sh = new Shape();
        }
        if(x_y_w_h_sh){
            if (x_y_w_h_sh[0]) { sh.x = x_y_w_h_sh[0] };
            if (x_y_w_h_sh[1]) { sh.y = x_y_w_h_sh[1] };
        }
        if(property){
            for (i = 0; i < property.length; i++) {
                if(property[i] && property[i].length > 1){
                    sh[property[i][0]] = property[i][1];
                }
            }
        }
        if(graphics){
            for (i = 0; i < graphics.length; i++) {
                if(graphics[i] && graphics[i].length > 1){
                    sh.graphics[graphics[i][0]].apply(null, graphics[i][1]);
                }
            }
            
        }
        if(x_y_w_h_sh){
            if (x_y_w_h_sh[2]) { sh.width = x_y_w_h_sh[2] };
            if (x_y_w_h_sh[3]) { sh.height = x_y_w_h_sh[3] };
        }
        return sh;
    }
    public static function newSprite(x_y_w_h_sp:Array = null,property:Array=null,graphics:Array=null,addChild:DisplayObject = null):Sprite{
        var i:int;
        var sp:Sprite;
        if(x_y_w_h_sp && x_y_w_h_sp[4]){
            sp = x_y_w_h_sp[4];
        }else{
            sp = new Sprite();
        }
        if(x_y_w_h_sp){
            if (x_y_w_h_sp[0]) { sp.x = x_y_w_h_sp[0] };
            if (x_y_w_h_sp[1]) { sp.y = x_y_w_h_sp[1] };
        }
        if(property){
            for (i = 0; i < property.length; i++) {
                if(property[i] && property[i].length > 1){
                    sp[property[i][0]] = property[i][1];
                }
            }
        }
        if(graphics){
            for (i = 0; i < graphics.length; i++) {
                if(graphics[i] && graphics[i].length > 1){
                    sp.graphics[graphics[i][0]].apply(null, graphics[i][1]);
                }
            }
            
        }
        if(addChild){
            sp.addChild(addChild);
        }
        if(x_y_w_h_sp){
            if (x_y_w_h_sp[2]) { sp.width = x_y_w_h_sp[2] };
            if (x_y_w_h_sp[3]) { sp.height = x_y_w_h_sp[3] };
        }
        return sp;
    }

    public static function newTextField(x_y_w_h_txt_color_alpha:Array = null,property:Array=null,method:Array=null):TextField{
        var i:int;
        var ta:TextField = new TextField();
        ta.defaultTextFormat = defaultTextFormat;
        if(x_y_w_h_txt_color_alpha){
            if (x_y_w_h_txt_color_alpha[0]) { ta.x = x_y_w_h_txt_color_alpha[0] };
            if (x_y_w_h_txt_color_alpha[1]) { ta.y = x_y_w_h_txt_color_alpha[1] };
            if (x_y_w_h_txt_color_alpha[2]) { ta.width = x_y_w_h_txt_color_alpha[2] };
            if (x_y_w_h_txt_color_alpha[3]) { ta.height = x_y_w_h_txt_color_alpha[3] };
            if (x_y_w_h_txt_color_alpha[4]) { ta.text = x_y_w_h_txt_color_alpha[4] };
            if (x_y_w_h_txt_color_alpha[5]) { ta.textColor = x_y_w_h_txt_color_alpha[5] };
            if (x_y_w_h_txt_color_alpha[6]) { ta.alpha = x_y_w_h_txt_color_alpha[6] };
        }
        if(property){
            for (i = 0; i < property.length; i++) {
                if(property[i] && property[i].length > 1){
                    ta[property[i][0]] = property[i][1];
                }
            }
        }
        if(method){
            for (i = 0; i < method.length; i++) {
                if(method[i] && method[i].length > 1){
                    ta[i].apply(null, method[i][1]);
                }
            }
        }
        return ta;
    }
    /*
    //以下はテスト
    public static function pozObject(x:Number=NaN,y:Number=NaN,width:Number=NaN,hight:Number=NaN,obj:Object = null):Object{
        if(x){obj.x = x}
        if(y){obj.y = y}
        return obj;
    }
    public static function newBitmap(x:Number=NaN,y:Number=NaN,width:Number=NaN,hight:Number=NaN,bd:BitmapData = null):Bitmap{
        var b:Bitmap = new Bitmap(bd);
        if(x){b.x = x}
        if(y){b.y = y}
        return b;
    }
    */
}




import flash.display.Sprite;
class MultiLoaderClass extends Sprite{
	import flash.system.Security;
	import flash.net.URLRequest;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.display.Loader;
	//import flash.display.LoaderInfo;
	
	private var onComplete:Function = function(arg:Array=null):void{};
	//private var onOpen:Function = function():void{};
	private var loadNum:int;
	private var loadCompNum:int;
	private var error_array:Array = new Array();
	private var URLs_array:Array = new Array();
	private var _uniqueParam:String = "";
	
	public function set uniqueParam(uStr:String):void {
		//?timeSpan=30&listType=rating"
		if (uStr) {
			if (uStr.substr(0,2) == "?=") {
				_uniqueParam = uStr;
			}else {
				_uniqueParam = "?=" + uStr;
			}
		}else {
			_uniqueParam = "";
		}
	}
	public function get uniqueParam():String {
		return _uniqueParam;
	}
	
	public function MultiLoaderClass(_str:String = null,uStr:String = null){
		if(_str){
			Security.loadPolicyFile(_str);
		}
		uniqueParam = uStr;
	}
	
	public function setLoad(__item_array:Array = null, _onComp:Function = null):Array {
		loadCompNum = loadNum = 0;
		if(_onComp != null){
			onComplete = _onComp;
		}
		if (__item_array.length == 0) {
			loadNum ++;
			onComplete();
		}
		
		URLs_array = __item_array.concat();
		error_array = new Array();
		//onOpen = _onOpen;
		var _array:Array = new Array();
		var _length:int = __item_array.length;
		for (var i:int = 0; i < _length; i++) {
			error_array[i] = false;
			if (__item_array[i] == null) { continue };
			var _extension:String = __item_array[i].substr(-4,4).toLowerCase();//拡張子を取り出す。
			if (_extension == ".xml" || _extension == "html" || _extension == ".cfm") {
				loadNum ++;
				_array[i] = textFromURL(__item_array[i] + uniqueParam);
			}else if(_extension == ".jpg" || _extension == ".gif" || _extension == ".png" || _extension == ".swf"){
				loadNum ++;
				_array[i] = imgFromURL(__item_array[i] + uniqueParam);
			}else if(_extension == ".bin"){
				loadNum ++;
				__item_array[i] = __item_array[i].substr(0, __item_array[i].length - 4);
				_array[i] = binaryFromURL(__item_array[i] + uniqueParam);
			}else{
				loadNum ++;
				_array[i] = textFromURL(__item_array[i] + uniqueParam);
				//_array[i] = null;
			}
		}
		
		return _array;
	}
	private function binaryFromURL(__url:String):URLLoader{
		var _loader:URLLoader = new URLLoader();
		_loader.dataFormat = URLLoaderDataFormat.BINARY;
		_loader.addEventListener(Event.COMPLETE,completeHandler);
		_loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
		_loader.load(new URLRequest(__url));
		return _loader;
	}
	
	private function textFromURL(__url:String):URLLoader{
		var _loader:URLLoader = new URLLoader();
		_loader.addEventListener(Event.COMPLETE,completeHandler);
		_loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
		//_loader.addEventListener(Event.OPEN,openHandler);
		_loader.load(new URLRequest(__url));
		return _loader;
	}
	
	private function imgFromURL(__url:String):Loader{
		var _loader:Loader = new Loader();
		_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
		_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
		//_loader.contentLoaderInfo.addEventListener(Event.OPEN,openHandler);
		_loader.load(new URLRequest(__url));
		return _loader;
	}
	
	private function completeHandler(event:Event = null):void {
		loadCompNum ++;
		if(loadCompNum == loadNum){
			onComplete(error_array);
		}
	}
	/*
	private function openHandler (event:Event):void {
		if(Math.random()>0.95){
			trace ("読み込みを開始した");
			//event.currentTarget.contentLoaderInfo.close();
			var str:String = event.currentTarget.toString().substr(8);
			if(str == "LoaderInfo]"){
				//event.currentTarget.contentLoaderInfo.close();
				//event.target.contentLoaderInfo.close();
				//event.currentTarget.close();
				//event.target.close();
			}else if(str == "URLLoader]"){
				event.currentTarget.close();
				completeHandler();
			}
			
			//completeHandler();
			//onOpen();
		}
	}
	*/
	private function ioErrorHandler(event:IOErrorEvent):void {
		//event.text = "Error #2035: URL が見つかりません。 URL: file:///~~~~~";
		//event.text = "Error #2036: 読み込みが未完了です。 URL: http://~~~~~";
		//から、URLのみを取り出す。
		//trace(String(event.text).substr(String(event.text).indexOf(" URL: ")+6),"*****");
		for (var i:int = 0; i < URLs_array.length; i++) {
			var _str:String = String(event.text).substr(String(event.text).indexOf(" URL: ")+6).substr(-URLs_array[i].length);
			if(URLs_array[i] == _str){
				error_array[i] = true;
			}
		}
		completeHandler();
	}
}