Have a look (Types vs. Arrays)

BlitzMax Forums/BlitzMax Programming/Have a look (Types vs. Arrays)

Hi,

I'm working on a particle-sys atm, just to get comfort with BMax and OGL. I asked me what's faster to use: Types within Types (i.e. Field pos:TVector3) or Arrays (i.e. Field pos#[3]).

So I wrote a test-app with interesting results:
Types are faster to create, faster accessible and use less memory. Not what I expected.

Would you mind to run this for yourself, maybe I got an error in my code.

Strict

Type TFloat3
	Field f1#,f2#,f3#
	Function Create:TFloat3(v1#,v2#,v3#)
		Local me:TFloat3=New TFloat3
		me.f1=v1
		me.f2=v2
		me.f3=v3
		Return (me)
	End Function
End Type

Type ptype
	Field f:TFloat3
	Function Create:ptype(v1#,v2#,v3#)
		Local me:ptype=New ptype
			me.f=TFloat3.Create(v1,v2,v3)
		Return (me)
	End Function
End Type

Type parray
	Field f#[3]
	Function Create:parray(v1#,v2#,v3#)
		Local me:parray=New parray
		me.f[0]=v1
		me.f[1]=v2
		me.f[2]=v3
		Return (me)
	End Function
End Type

Local in$=Input ("How many elements?")
If in="" Then in="500000"
Local numObj:Int=Int(in)

Global atypes:ptype[numObj]
Global aarray:parray[numObj]


Global memory:Int
Global time:Int
Global n:Int
Global f1#,f2#,f3#

'wait some time
Print "please wait..."
Delay(5000)

'create and fill array
memory=GCMemAlloced()
time=MilliSecs()
For n:Int=0 To numObj-1
	aarray[n]=parray.Create(1.0,2.0,3.0)
Next
Print "Creating "+numObj+" parrays: "+(MilliSecs()-time)
Print "used memory: "+(GCMemAlloced()-memory)

'write array
time=MilliSecs()
For n=0 To numobj-1
	aarray[n].f=[1.0,2.0,3.0]
Next
Print "Write to "+numObj+" parrays: "+(MilliSecs()-time)

'Read array
time=MilliSecs()
For n=0 To numobj-1
	f1=aarray[n].f[0]
	f2=aarray[n].f[1]
	f3=aarray[n].f[2]
Next
Print "Read from "+numObj+" parrays: "+(MilliSecs()-time)


'create and fill types
memory=GCMemAlloced()
time=MilliSecs()
For n:Int=0 To numObj-1
	atypes[n]=ptype.Create(1.0,2.0,3.0)
Next
Print "-----------------"
Print "Creating "+numObj+" ptypes: "+(MilliSecs()-time)
Print "used memory: "+(GCMemAlloced()-memory)

'write  types
time=MilliSecs()
For n=0 To numObj-1
	atypes[n].f.f1=1.0
	atypes[n].f.f2=2.0
	atypes[n].f.f2=3.0
Next
Print "Write to "+numObj+" ptypes: "+(MilliSecs()-time)

'read types
time=MilliSecs()
For n=0 To numObj-1
	f1=atypes[n].f.f1
	f2=atypes[n].f.f2
	f3=atypes[n].f.f3
Next
Print "Read from "+numObj+" ptypes: "+(MilliSecs()-time)

End


Test 1

How many elements?100
please wait...
Creating 100 parrays: 0
used memory: 4982
Write to 100 parrays: 0
Read from 100 parrays: 0
-----------------
Creating 100 ptypes: 0
used memory: -3476
Write to 100 ptypes: 0
Read from 100 ptypes: 0


Error here as you clearly see

Test 2

How many elements?100000
please wait...
Creating 100000 parrays: 137
used memory: 4797572
Write to 100000 parrays: 72
Read from 100000 parrays: 5
-----------------
Creating 100000 ptypes: 57
used memory: 3199172
Write to 100000 ptypes: 9
Read from 100000 ptypes: 6


Maybe GCMemAlloced() return wrong values when using low elementcounts - that's all I clearly see.

as I understand it GCMemAlloced is the total of a pool of memory, which can contain a bit of unused slack, when the GC releases and object the unused memory is often kept for later use, maybe this is whats is happening

test1 is just using some of the slack and doesnt need to allocate memory from the system because it has enough room in its pool

Forget 'bout GCMemAlloced...
Am I the only one beeing suprised that types within types are faster than arrays?

Not sure but isn't this because you're directly accessing the link for the object rather than accessing the object via a list? It's normally the list access vs indexed acces that makes arrays faster.