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