ActionScriptで配列とかディープコピーするのはどんな方法が一般的なんだろうと思って調べてました。
今回は、僕のようなAS初級者向けの内容です。
以下のエントリーでByteArrayを使ってオブジェクトをディープコピーする例がありました。
ActionScriptでディープコピー
おぉ、けっこう簡単。後追いですが僕も検証してみました。
var list:Array = [0,1,2,3]; var ba:ByteArray = new ByteArray(); ba.writeObject(list); ba.position = 0; var copy:Array = ba.readObject(); trace(copy); copy[2] = 4; trace(copy); trace(list); //出力結果 0,1,2,3 0,1,4,3 0,1,2,3
うん、できてる。
次は100万個の要素をfor文でガリガリコピーしたものと速度比較。
var list:Array = new Array();
for(var i:int = 0; i < 1000000; i++) list.push(Math.random());
trace("List of "+list.length+" elements.");
//for
var ts1:Number = getTimer();
var copy1:Array = new Array();
for(var j:int = 0; j < list.length; j++) copy1.push( list[j] );
var te1:Number = getTimer();
trace("for(): "+(te1-ts1)+"ms");
//ByteArray
var ts2:Number = getTimer();
var ba:ByteArray = new ByteArray();
ba.writeObject(list);
ba.position = 0;
var copy2:Array = ba.readObject();
var te2:Number = getTimer();
trace("ByteArray: "+(te2-ts2)+"ms");
//出力結果
List of 1000000 elements.
for(): 363ms
ByteArray: 464ms
あれ。forの方が早い。ループ処理を最適化してさらに検証。
//最適化前
var ts1:Number = getTimer();
var copy1:Array = new Array();
for(var j:int = 0; j < list.length; j++) copy1.push(list[j]);
var te1:Number = getTimer();
trace("for(): "+(te1-ts1)+"ms");
//最適化後
var ts1:Number = getTimer();
var copy1:Array = new Array();
var len:int = list.length;
for(var j:int = 0; j < len; j++) copy1[j] = list[j];
var te1:Number = getTimer();
trace("for(): "+(te1-ts1)+"ms");
//出力結果
List of 1000000 elements.
for(): 217ms
ByteArray: 468ms
ByteArrayで配列コピーすると遅いってことでいいのか。
ただ、100万個も要素コピーすることなんてまずないと思いますけど;
ここで、変数に配列名(copy1 = list)を代入すると配列のシャローコピー(浅いコピー)になりますが、
ループで要素を1つずつ入れてやれば(copy1[j] = list[j])ディープコピーができます。
C言語でも「配列名はアドレス」って大学生の時にしつこく教えられた記憶があります。
また、配列のコピーならArray.concat()、Array.slice()を使っても出来ます。
//slice()
var ts1:Number = getTimer();
var copy1:Array = list.slice(0, list.length);
var te1:Number = getTimer();
trace("slice(): "+(te1-ts1)+"ms");
//concat()
var ts2:Number = getTimer();
var copy2:Array = list.concat();
var te2:Number = getTimer();
trace("concat(): "+(te2-ts2)+"ms");
//出力結果
slice(): 46ms
concat(): 32ms
concat。速い。
なんか時間をムダにした気がする。。。。
How i may contact the administrator of a site? I have a question.