Hi, I wrote an external interfacing wrapper for Raylib, and duplicated their BunnyMark demo. I was surprised that I could spawn far less bunnies without a lot of FPS drop. After some profiling, it turned out that updating the positions of each bunny by+= velocity was taking a very long time, something like 50+ms on 20,000 objects.
What would be the fastest way to do this just inside dolphin? I know that the theoretical fastest way would probably be to write a c++ library to do it.
The way I was doing it was I had bunny objects, with points for position and velocity. They were stored in an OrderedCollection, and then a do:[:each| each position: each position + each velocity].
I know very little about optimization in Smalltalk so I would appreciate any advice on this topic, thanks - Jacob
Yes, I've already been rendering games with opengl. I'm using GLFW to create the window, not dolphin.
The problem isn't a rendering issue - it's that running the code I gave above takes a very long time to execute.
Here is an example code that illustrates the issue a := OrderedCollection new.
1 to: 20000 do: [:count|
a add: (2@2)].
Time millisecondsToRun: [
1 to: 20000 do: [:index|
(a at: index) x: index]
]
would give like 50-80 ms to run the second block.
This is not the exact code in my update loop, but basically I am updating the position of 20,000 or so game objects every frame and it's taking around 50-80 ms to run code like the above. I was just seeing if there is a more performant way of updatinga large number of objects in dolphin, i.e. perhaps I shouldnt use a class at all for my game objects, and store everything in an array, an orderedCollection, I'm not really sure.
a := OrderedCollection new.
1 to: 20000 do: [:count|
a add: (2@2)].
Time millisecondsToRun: [
1 to: 20000 do: [:index|
(a at: index) x: index]
]
would give like 50-80 ms to run the second block.
a := OrderedCollection new.
1 to: 20000 do: [:count|
a add: (2@2)].
Time millisecondsToRun: [
1 to: 20000 do: [:index|
(a at: index) x: index]
]
would give like 50-80 ms to run the second block.
In my machine run in 2 millisecods.
What version of Dolphin are you using ?
Also as John asked which hardware do you have in your machine ?
regards,
bruno
Sorry about that, that wasn't actually the code that was taking a while, actually what I was doing in my code was:
Object subclass: #Bunny
instanceVariableNames: 'position speed color'
classVariableNames: ''
poolDictionaries: ''
classInstanceVariableNames: ''
(accessors for position, speed and color)
bunnies := OrderedCollection new.
1 to: 20000 do: [:index| |bunny|
bunny := Bunny new position: 200@200; speed: 5@5;yourself.
bunnies add: bunny.
].
and then my game loop would need to call the below to update them once per frame (of course I wasn't using time millisecondsToRun to run during the actual game loop)
Time millisecondsToRun:[bunnies do: [:each|
each position: each position + each speed.
((each position x + (32)) > 800) | ((each position x + 32) < 0) ifTrue: [each speed x: each speed x* -1].
(each position y + (32)) > height | ((each position y + 32) < 0) ifTrue: [each speed y: each speed y* -1].
]].
which takes 13 milliseconds on my dolphin (my processor is an i7 7700k). However when I profiled the same code in c++ it would only take about 200 microseconds.
Anyway, thanks for the responses, I will check the profiler in dolphin to see if I can optimize this.
Thanks John. Do you think there is a way to further optimize it, for example not using points, or some other different way of structuring the data?
Optimization in smalltalk is a topic I am interested in but have read nothing about as far as I remember. Eventually I guess I will have to learn c++ better
so I can check out what is actually happening behind the scenes.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 292 |
Nodes: | 16 (2 / 14) |
Uptime: | 183:55:36 |
Calls: | 6,616 |
Files: | 12,165 |
Messages: | 5,314,636 |