Code archives/Miscellaneous/faster nested loops
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
well this is a little type I put together to improve the speed of my physics engine which uses many nested loops... lists in general slow down nested loops a lot more than arrays do so I decided to make my own little type to do the array stuff behind the scenes so its almost like your using a tlist without the slowdown if you have a lot of objects. speed example posted below, on my pc, the arrays take about two thirds of the time the tlists do... which is a lot when trying to shave off a few milliseconds edit: all known bugs fixed! see examples for how to delete things from an array, it is a little hard to get why but it is the only way to keep the array system fast and flexible and error proof... you must also loop through them backwards if you want to delete everything in one fowl swoop... but you may delete in any order going one at a time | |||||
Type Array 'array to act like tlist except a million times faster Field a:Object[10] 'starts off with 100 objects... Field last:Int Function Create:Array(Length:Int) Local a:array = New array a.a = a.a[..length] Return a:array End Function Method length:Int() Return (last-1) End Method Method add:Int(obj:Object) a[last] = obj If a.length < last+2 Then a = a[..(a.length+1000)] EndIf last :+ 1 Return (last-1) End Method Method Getbyindex:Object(in:Int) Return a[in] End Method Method remove:Object(index:Int) a[index] = a[last-1] a[last-1] = Null last :- 1 Return a[index] End Method End Type |
Comments
| ||
example using arrays example using tlists instead if you modify the examples not to use nested loops they are almost the same but using 3 nested loops will increase the difference in the time it takes |
| ||
Great idea, and the examples certainly showed the difference here. (About a second slower with lists -- 1300 ms vs 2200 ms.) |
| ||
I think I see a problem with your array type. If somebody is holding on to the indexes into the array of their objects for fast reference, and then remove an object, your are moving the last one to the place in the list where the removed one was. Which means the index the user is holding for that object is wrong... |
| ||
Also, I just noticed for your length method, you might want to return last, not last-1. With nothing in the list, do you want the length to be -1 or 0. I would think 0. |
| ||
Hi Nate the Great, there is error in your example using arrays. I'm using BM 1.36, and thereFor j = 0 To foo.fooarray.length() f:foo = foo(foo.fooarray.getbyindex(j)) foo.fooarray.remove(f:foo,f.index) Next I have a message: "Unhandled Exception: Attempt to acces field or method of Null object". I do that: For j = 0 To foo.fooarray.length() f:foo = foo(foo.fooarray.getbyindex(j)) DebugLog "index: "+f.index DebugLog "foo.length: "+foo.fooarray.length() foo.fooarray.remove(f:foo,f.index) Next and my output looks like that: DebugLog:index: 0 DebugLog:foo.length: 1000 DebugLog:index: 1 DebugLog:foo.length: 999 DebugLog:index: 2 DebugLog:foo.length: 998 DebugLog:index: 3 ... DebugLog:index: 498 DebugLog:foo.length: 502 DebugLog:index: 499 DebugLog:foo.length: 501 DebugLog:index: 500 DebugLog:foo.length: 500 After index=500 program crash. It's mean that index increase but foo.length decrase, and they meet in the middle. Edit: Maybe this can help: for j = foo.fooarray.length() To 0 Step -1 |
| ||
The For loop just needs to be either an Until or To length -1. |
| ||
Thanks TaskMaster, but this code:For j = 0 To foo.fooarray.length() f:foo = foo(foo.fooarray.getbyindex(j)) foo.fooarray.remove(f:foo,f.index) Next and this: For j = 0 To foo.fooarray.length()-1 f:foo = foo(foo.fooarray.getbyindex(j)) foo.fooarray.remove(f:foo,f.index) Next crash that same, exacly after this moment: DebugLog:index: 500 DebugLog:foo.length: 500 Is it work for you this Nate the Great's example? Sorry for my english. |
| ||
I don't think you can loop like that. I think the .length in the For loop is only going to get evaluated once. So it will always try to go to the arrays original length, even though the length is decreasing because you are removing items. I don't see why you would do that anyway, since you should just be able to clear it. |
| ||
You have a right TaskMaster, but this example: doesn't work on my machine. Error "Unhandled Exception: Attempt to acces field or method of Null object" is in line foo.fooarray.remove(f:foo,f.index) I don't know why this doesn't work :/. I have XP sp2, BM1.36. |
| ||
hmm sorry about the problems guys... ill look into it... if its not working, could be a real problem.. and you should get different results on different chip sets, some are more optimized for the way arrays work, some more so for tlists |
| ||
all fixed! you must note that you have to loop through them backwards to delete them correctly... but deleting one by one you can go in any order... there is also a special way you must delete them... and the "special" way keeps the array nice and clean and keeps it goin fast |
| ||
I see you're putting an impressive amount of effort toward optimization here ;) |
| ||
its all needed though for what im planning :) |
Code Archives Forum