Slices speed 'bumps'
BlitzMax Forums/BlitzMax Programming/Slices speed 'bumps'
| ||
I noticed major slowdown in my code which seems to be caused by slices. I have a loop that uses slices to make several arrays one size bigger each iteration. With one array the speed is ok. With more than one array though the time it takes to perform the slices seems to be non-linear - more arrays equals more severe slowdown. I tried looking into it and with slices there seems to be a speed 'bump' every so often - whereas normally it takes 0-1ms to perform, it might takes 10ms or more on occasion. I thought this might be caused by the GC system but even using GCCollect every frame doesn't seem to get rid of the speed bumps. So, is this normal behaviour or should slices be working faster? Here's a small test function: Strict GCSetMode 1 Global a[1] Global b[1] Global c[1] Global d[1] Global e[1] Global f[1] Global g[1] Global h[1] Global ms0=MilliSecs() Global ms=0 Global i=0 For i=1 To 10000 ms=MilliSecs() a=a[..i+1] b=b[..i+1] c=c[..i+1] d=d[..i+1] e=e[..i+1] f=f[..i+1] g=g[..i+1] h=h[..i+1] ms=MilliSecs()-ms If ms>10 Print "Loop Time: "+ms+" (i="+i+")" GCCollect() Next Print "Program Time: "+String((MilliSecs()-ms0)/1000.0) End |
| ||
Slices are slow, thats the tradeof for being able to resize them at runtime without losing their content. If you need to resize a lot, TList is the way to go, as it is a dynamic structure without an overhead for its dynamic sizing. |
| ||
Can you not just resize in batches? |
| ||
The optimal way for resizing arrays is only doing *2 , /2 in size ... that way the averange cost per operation goes to 1 ie optimum. -> if you need more elements that the array can hold, double its size. If you have less objects in the array than half of its length, resize it to half of its length. That should give some acceptable results :) *still, arrays would not be a highly dynamic structure, so if it happens that you put and remove half of the data every frame, it won't help much* |
| ||
To proof my little "blubb" on slicing with *2 which comes from theoretical informatics science, I've a little testapp here:Strict Rem Array Slicing Performance Test End Rem Local testarray:Int[0] Local time1:Int = MilliSecs() For Local i:Int = 1 To 65536 If i > testarray.length testarray = testarray[..testarray.length + 1] testarray[i-1] = i Next time1 = MilliSecs() - time1 Print "Testrun 1 (slice with size 1): " + time1 Local time2:Int = MilliSecs() For Local i:Int = 1 To 65536 If i > testarray.length testarray = testarray[..testarray.length * 2] testarray[i-1] = i Next time2 = MilliSecs() - time2 Print "Testrun 2 (slice with factor 2): " + time2 Print "Ratio of Run 2 to Run 1: " + (Float(time2) / time1) End You can replace the "to value" with any power of 2 + 1. I first wanted to do it with 1 to 1048577, but after 30 seconds I got bored. As I already know that the *2 will only call slice 20 times compared to 1048577, I don't think its hard to see what ration will result from that ;) |