Speed Question

Blitz3D Forums/Blitz3D Beginners Area/Speed Question

Gauge(Posted 2004) [#1]
Say you 500 examples of player, is there any faster way to do this?

time1=millisecs()
For p.player=each player
For px.player=each player
writeline p\stream, px\x#+","+px\y#+","+px\z#+","+px\rot#
next
next
time2=millisecs()
time#-time2-time1


I get anywehre between 700 and 1200 for my time#

Will while be faster then two for next or two whiles, or? any suggestions? Or perhaps i can cut it down to one long line? Thanks for any input.


WolRon(Posted 2004) [#2]
Perhaps if you changed this line:
writeline p\stream, px\x#+","+px\y#+","+px\z#+","+px\rot#
into a line that writes a static string (as opposed to a dynamically concatenated one), it may improve the speed. Something like:
Dim coords$(500)
num = 0
For px.player = Each player
  coords$(num) =  px\x#+","+px\y#+","+px\z#+","+px\rot#
  num = num + 1
Next
total = num

time1 = Millisecs()
For p.player = Each player
  For num = 0 to total
    WriteLine p\stream, coords$(num)
  Next
Next 
time2 = Millisecs() 
time# = time2 - time1 



Floyd(Posted 2004) [#3]
No matter how the strings are handled that's still a quarter of a million lines of text.

Was this really the intention? I would have expected something like
For p.player = Each player 
	WriteLine p\stream, p\x#+","+p\y#+","+p\z#+","+p\rot# 
Next

which writes each player's data once, to the stream indicated in p\stream.


Gauge(Posted 2004) [#4]
Thanks for the input guys. I think i'm gonna try making one giant line/string. I'll have to see how slow it is though.

p.s. Floyd, its for multiplaer, so it has to write each player to each player.


NewtSoup(Posted 2004) [#5]
That looks like server code to me. And it is sending the position of every player to all the players , your fragment on its own, Floyd, would only send the update to one client. Whats more all your code is doing is sending the data of one client to itself.

perhaps sending a singler bigger packet to each player might be more efficient? IE compile the currrent position update into a single packet. Assuming a float is 8 bytes thats 500*8*4 = 16k of data minimum to send to each client on position alone assuming there are 500 clients (which is a lot and do they REALLY all need to know everyone elses position?)

Also I would use writeFloat() to the stream rather than cating a string together as a string of "2.1242455236" (12 bytes) takes longer to send than writeFloat(2.124245523) because the Float takes up fewer bytes, 4 or 8 I can't remember what blitz uses for floating point math.

anyway what you are trying to do is send 500*500*8*4 = 7.8Mb (or 61Mbit) of data each program cycle. (update 500 positions to 500 clients each with 4 variables at 8 bytes each.)
Seeing as you say this is a multiplayer game with a max of (I hope :P ) 500 players I am guessing this is for internet play (unless you are having a truly massive lan party). Even with a 100mb leased line this is going to take at least 620ms to send so you really really need to think about the following things:

Reduce the data as much as possible IE reduce the precision of your floats to what is actually needed perhaps ints will do that will halve the data size for each player.

Reduce Max_Players (works every time that one.. I find with max_players = 1 the data goes so fast, kind of boring tho)

I think then compile a single large packet to send. Then compress the packet. (look at huffman encoding/binary space partitioning) and then send the compressed packet down the stream, probably have to do it in writebytes() with a header containing the length of the data you are about to send so that the client knows when to stop reading. (thats kind of gnarly but it will work most of the time)


NewtSoup(Posted 2004) [#6]
That probably sounds like a lot of pre-processing but I promise you your machine can crunch the numbers faster than it can read/write them off the net.