The automatic memory management of Blitzmax
BlitzMax Forums/BlitzMax Programming/The automatic memory management of Blitzmax
| ||
hello I'm making 2D physics engine with Blitzmax. But, it is too slow to use "type vector2d" made with blitzmax. The task that numerous vectors are generated and destroyed for a loop is too slow. I think that this task is slower than another task with C++ by 100 times. The automatic memory management of blitzmax is very useful, but slow for this kind of task. I tried to use not "user defined type" but combination of array ptr. and functions, but array is processed like "user defined type" too. I'd like to use data structure constructed by 2 float number. Can I make directly referenced struct in Bmax? I don't care if it is in OOP or not. The source below is for test. The elapsed times to process this are about 0ms in C++, and 56ms in Bmax. Oh my god. --------------------------------- c++ source ------------------------------------------ #include <iostream> #include <ctime> #include <conio.h> class Vector { public: float x; float y; Vector(void); Vector(float xi, float yi); }; inline Vector::Vector (void) { x=0; y=0; } inline Vector::Vector(float xi, float yi) { x=xi; y=yi; } inline Vector operator+(Vector u, Vector v) { return Vector(u.x + v.x, u.y + v.y); } int main() { int const ITERATIONS = 100000; long t = std::clock(); int loop; Vector A = Vector(3,3); Vector B = Vector(2,5); Vector C = Vector (0,0); for (loop = 0 ; loop < ITERATIONS ; loop++ ) { Vector A = Vector(1,2); Vector B = Vector(3,4); Vector C ; C=A+B; } t = std::clock() - t; std::cout << ITERATIONS << " iterations took " << t << " millisecs.\n"; getch(); return 0; } ------------------------------BMAX source------------------------------------------ Type tVec Field x : Float Field y : Float Method add : tvec( _v : tvec) Local v : tVec = New tvec v.x=self.x+_v.x v.y=self.y+_v.y Return v EndMethod Function create : tvec (_x#=0.0,_y#=0.0) Local v: tvec = New tvec v.x=_x v.y=_y Return v EndFunction EndType Const ITERATIONS = 100000 Local t = MilliSecs() For Local i = 0 To ITERATIONS Local va: tvec = tvec.create(3,3) Local vb : tvec = tvec.create(3 , 4) Local vc : tvec vc = va.add(vb) Next Print ITERATIONS + " iterations took " + (MilliSecs() - t) +" millisecs." |
| ||
Why do you even need to create and destroy numerous instances every frame? Just creating or just destroying I could see, but if you're doing both, why don't you just pool and reuse them? |
| ||
What that guy over there said. E.g., Strict Type Vector Field x#, y# End Type Const VCACHE_INIT%=256 Global vectorUsed@[VCACHE_INIT] memset_(vectorUsed,2,VCACHE_INIT) Global vectorCache:Vector[VCACHE_INIT] For Local i:Int = 0 To vectorCache.Length-1 vectorCache[i] = New Vector Next Function GetVector:Vector( ) For Local i:Int = 0 To vectorCache.Length-1 If vectorUsed[i] = 2 Then vectorUsed[i] = 3 Return vectorCache[i] EndIf Next Local from% = vectorCache.Length vectorCache = vectorCache[..from*2] vectorUsed = vectorUsed[..from*2] memset_( Varptr vectorUsed[from+1], 2, from ) vectorUsed[from]=3 For Local i:Int = from To vectorCache.Length-1 vectorCache[i] = New Vector Next Return vectorCache[from] End Function Function FreeVector( vec:Vector ) For Local i:Int = 0 To vectorCache.Length-1 If vec = vectorCache[i] Then vectorUsed[i] = 2 Return EndIf Next End Function |
| ||
Perhaps more optimisation can be done by Mark? Whats the perfomance when you turn on manual garbage collection? |
| ||
Const ITERATIONS = 100000 GCSetMode(2) Local t = MilliSecs() For Local i = 0 To ITERATIONS Local va : tvec= vec(3 , 3) Local vb :tvec = vec(2 , 5) Local vc:tvec=va.add(vb) GCCollect() Next Print MilliSecs() - t 100000 iterations took 119 millisecs. -------------------------------------------------- For Local i = 0 To ITERATIONS Local va : tvec= vec(3 , 3) Local vb :tvec = vec(2 , 5) Local vc:tvec=va.add(vb) Next GCCollect() 100000 iterations took 548 millisecs. -_-; |
| ||
Put GCCollect at the beginning of the loop and tell us what that does. |
| ||
Thx, Noel. But, It is too complicated for a wide use. And in some intances, it's slower than using new method. |
| ||
I put Gccollect at the bigging of the loop. 100000 iterations took 123 millisecs. no changes. |