Forum Replies Created
- 
		AuthorPosts
 - 
		
			
				
The immutable part threw me a little bit because obviously vectors are going to change if you use them to store coordinates for game objects and whatnot, but I guess that the majority of the time the vectors you create will be temporary and only used to do calculations before being discarded straight away, so overall a struct works out a lot better.
So if in the majority of cases the data will not change in its lifetime then a struct is probably a good idea, but for objects that will persist for a while and contain data that changes overtime then classes are the way to go. And of course if you need to extend/inherit then you don’t have a choice but use classes.
I was looking at my particle engine and wondering where I can use structs, but I don’t think there’s many other places other then the vectors/matrices (which will still make a big difference). I thought about the particles themselves being structs but they are basically objects that will persist for a while and have plenty of data that changes overtime. Plus they have hierarchy and such.
I did make the tlCollisionResult a struct though as it’s basically filled with the results of the collision and then discarded once used so it made sense there. That got me another 100k collisions per second so up to 5.2mill now, I think that’ll do for now!
New update just pushed. Getting silly now, I’ve converted tlVector2 to a struct, result:
Collisions done in 1 second: 5138002
Will do matrix next, but that won’t make much difference as they’re not used to detect collisions but obviously might help with the tform stuff. I’ll have to check if there’s anything else I can convert to struct! The quadtree sample has dropped to 6-7 ms now which is also nice to see!
@abakobo: Thanks, i find optimisation very interesting. Looks like Structs in MX2 will provide some nice advantages in this case
I like the sound of the incremental garbage collection, hopefully it eliminates the odd stutter that bmx was prone to.
Why is MX2 so much faster? Is it just that c++ compilers have come a long way and BMX compiler hasn’t updated to take advantage of any additional CPU trickery?
Next think I would suggest looking into is perhaps using a struct for vector2d instead of a class.
Yeah, that’s exactly where I was going next, I was looking at possibly using the structs already there in the std/geom module but I’ll probably just convert my own as they have a couple of extra methods I use (assuming they’ll work with structs).
That’s better! it’s insanely fast now, getting:
MX2: Collisions done in 1 second: 3694513
BMX: Collisions done in 1 second: 1241045So almost 3 times faster than bmx on my PC. The quadtree example is also where it should be as well, a solid 7-8ms when drawing a whole screen with 10000 objects, max goes from 7-10, the rendering will be a bit more of a normaliser there though I guess. BMX sort of flicks up to 10 every other second, I wonder if that’s the garbage collector cleaning things up?
Well done for finding the spanner!
Will keep tidying up the module and see if I can squeeze out any more speed, maybe I can get some particles going before the release
Wow, that sounds a bit more like it!
Looking forward to trying the new version out. Had a feeling there must be a spanner in the works somewhere
If MX2 can be shown to out perform Max then that could be a real clincher for a lot of people to make the jump over.
Thanks for testing it.
Maybe arrays in M2 are the issue, I should try reversing it and add the arrays into the Max version to see what performance hit it takes. The vertices of the polygons are stored in an array, so maybe accessing those values are slow?
Ok, so I changed the arrays to variables like they are in Blitzmax. I can see why I switched to arrays in monkey – because there was no variable pointers. I was using pointers in max and changing the values in the function without needing to pass them back.
So now, the new result in Monkey is:
Collisions done in 1 second: 567293
Decent improvement! Will keep looking for more improvements.
Both algorithms should be pretty much the same, with the exception of how objects move within the quadtree. In Blitzmax I’m able to remove from the quad tree node list and add them back again, but in monkey 2 I have to remove them and then batch them up to be added back at the end of the update due to the concurrent list modification, but I should think the time is about the same, it’s just adding them back at the end rather then on the fly.
But, I do have another much more simple test where the code is pretty much the same and doesn’t use the quadtree at all. This just checks for a collision between 2 polys as many times as it can in 1 second, hopefully it should be a lot more easy to diagnose:
Monkey
Monkey123456789101112131415161718192021222324#Import "<std>"#Import "<mojo>"#Import "<timelinefx>"Using std..Using timelinefx..Using mojo..Function Main()New AppInstanceLocal verts:= New Float[](0.0, 0.0, -150.0, 100.0, 50.0, 150.0, 185.0, 100.0, 300.0, 0.0)Local poly1:= CreatePolygon(150, 150, verts)Local poly2:= CreatePolygon(450, 250, verts)Local time:Int = App.MillisecsLocal collisions:IntPrint "Starting test..."While App.Millisecs - time <= 1000CheckCollision(poly1, poly2)collisions+=1WendPrint "Collisions done in 1 second: " + collisionsEndMax:
Monkey123456789101112131415161718SuperStrictImport rigz.collisionLocal verts:Float[] = [0.0, 0.0, -150.0, 100.0, 50.0, 150.0, 185.0, 100.0, 300.0, 0.0]Local poly1:tlPolygon = CreatePolygon(150, 150, verts)Local poly2:tlPolygon = CreatePolygon(450, 250, verts)Local time:Int = MilliSecs()Local collisions:IntPrint "Starting test..."While MilliSecs() - time <= 1000CheckCollision(poly1, poly2)collisions = collisions + 1WendPrint "Collisions done in 1 second: " + collisionsResults here (on Windows PC i7) in release mode:
Monkey:
Collisions done in 1 second: 192950BlitzMax:
Collisions done in 1 second: 1214547Blitzmax doesn’t mess about! In fact in Blitzmax it does 217000+/- in debug mode. I did double check that both polys in both versions are positioned exactly the same, they just slightly overlap each other.
I’ve just noticed one difference between each code, the monkey version is creating 2 arrays each check (with a length of 2 each), the max version is creating 4 variables instead, but that wouldn’t make a difference though would it? Will change it anyway just to check…
Go ahead it’s there to be used
I will be making changes to it but not anything that will affect the usage of it with the exception that I’ll probably switch to using lambdas for handling the collision events. I think they will be better then using interfaces which was the best solution I could think of in monkey 1. In Blitzmax I used function pointers which worked well too.
I’ll try and edit the first post, see if it works now…
I think you want:
canvas.BlendMode = BlendMode.Alpha
I was just curious about how you actually pass an iterator to a function. Or how do you pass a “type” that is a sub type (if that’s what it’s called) of a class. And in preparing an example I’ve actually found out how
–
[/crayon]Monkey12345678910111213141516171819202122232425[crayon-5cba857ca5c01190447601 inline="true" ]#Import "<std>"Using std..Class tlQuadTreeNodeEndFunction DoSomethingWithIterator(i:List<tlQuadTreeNode>.Iterator)EndFunction Main()Local list:=New List<tlQuadTreeNode>list.AddLast(New tlQuadTreeNode)Local it:=list.All()While not it.AtEndDoSomethingWithIterator(it)it.Bump()WendEndBefore I was just using List.Iterator without specifying the <generic> bit.
Ahh thanks
Incidentally, I searched for “casting” on this forum and it only showed the first post of that thread, none of the replies so I didn’t think it’d been answered.
Thanks I’ll give that try!
Seems to work quite well so far, thanks
there was an initial issue with REM and END (in caps) not recognised but a search and replace sorted that (you might want to add it though non-the-less). I shall have to take a look at gradle and see if I can set that up as well.
Great thanks! Will give it a try tomorrow
 - 
		AuthorPosts