Posts Tagged ‘concatenate

12
Mar
09

Fastest Way to Copy An Array: Concat() or Slice(0)

What is the fastest way to copy an array? Concat or Slice? There is only one way to find out. FIGHT!

OK, so we can dismiss any kind of for-loop – far too slow, so that leaves us with:
1) array.concat() – i.e. concatenate an array onto nothing and deliver that as a new array.
2) array.slice(0) – i.e. return a new array consisting of all of the elements of the old array – from 0 till the end (up to a max of 16777215)

I’ve set up an array with a cool 1million entries (ok, it is not big, and it is not clever so it certainly isn’t cool). I need to copy this. The following code executes each method once on every iteration. It keeps a running total and records the average time each takes. I’ve limited the code to 100 iterations.

package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.utils.*;
public class TestConcat extends Sprite
{
private var iteration_count:int=0
private var concat_total:int=0
private var slice_total:int=0
private var clone_total:int=0
private var tf:TextField = new TextField()
private var test_array:Array = [];

public function TestConcat():void
{
tf.x = tf.y = 100; tf.width = 600;
addChild(tf)

//Set up array to copy
for(var i:int = 0; i < 1000000; i++) test_array.push(i);
//Mouse click to rerun test
stage.addEventListener(MouseEvent.CLICK, go);
//First run
go()
}

private function go(e:Event = null):void
{
iteration_count=concat_total=slice_total=clone_total=0
addEventListener(Event.ENTER_FRAME, iterate)
}

//Loop through tests
private function iterate(e:Event=null):void
{
concat_total +=testConcat()
slice_total += testSlice()
clone_total += testByteArrayClone()
iteration_count++
tf.text = "Av. Concat time=" + (concat_total / iteration_count)
+ "ms Av. Slice time=" + (slice_total / iteration_count)
+ "ms Av. BA Clone time=" + (clone_total / iteration_count) + "ms";
if(iteration_count<99) removeEventListener(Event.ENTER_FRAME,iterate)
}

//test array slice
private function testSlice():int
{
var time_slice_start:Number = getTimer();
var slice_copy:Array = test_array.slice(0);
return getTimer()-time_slice_start
}

//test array concat
private function testConcat():int
{
var time_concat_start:Number = getTimer();
var concat_copy:Array = test_array.concat();
return getTimer()-time_concat_start
}

//test BA Clone method
private function testByteArrayClone():int
{
var time_concat_start:Number = getTimer();
var concat_copy:Array = clone(test_array);
return getTimer()-time_concat_start
}

//Clone method for Deep Objects(via Bruno)
private function clone(source:Object):*
{
var myBA:ByteArray = new ByteArray();
myBA.writeObject(source);
myBA.position = 0;
return(myBA.readObject());
}
}
}

On my laptop I’m clocking the concat at 14ms and the slice at over 29ms.

So a conclusive result. concat is twice the speed (with large arrays – the difference diminishes considerably with smaller arrays)

Give the code a few run throughs and see what you get. Let me know if your results are markedly different.

UPDATED:
I have updated the code and added a swf to try out here and the source code here

Fastest way to copy an array

Test the array copy for yourself


I’ve also added in a test for the Byte Array Clone method suggested by Bruno (see his comments below). This method seems a great one for copying ‘deep’ arrays – arrays of complex objects (arrays, objects or other types). In this context and test (copying shallow arrays) the instantiation, writing and reading adds too much overhead. I’ll need to test this in a useful context: with deep arrays.

Demo: Array Copy test
Source: Source.as

Advertisement



Categories

Reasons to be Creative 2012

FITC Amsterdam 2012

Flash on the Beach 2011

Flash on the Beach 2010

Swingpants at Flash on the Beach

Flash on the Beach 2009

Swingpants at FOTB2009

Twitter Updates