Post by tsh73 on Jan 7, 2021 15:15:43 GMT -5
First, thanks John for his code
libertybasiccom.proboards.com/thread/1446/3d-arrays-lb4s-dimensions
It's nice and clean and while reading makes perfect sense.
But it is said to be kinda slow
I enabled mainwin and saw it takes most of the time drawing points.
So I went and looked into it
Basically, drawing part is this
You see, for each color we set color value - issue "color" command - and LB has to execute it
(and it looks like
From other parts of code it looks like currently there only 2 colors used (actually second is background color)
I start wondering how much it takes and how fast we can get?
So here's a test
I open normal "for graphics_nsb_nf" window, it happen to be 312x322 points
Randomly filled 312x322 array with 0 or 1
and tried to plot 1 with red, 0 with blue
First attempt was just that
It ended up at 17000 ms (my machine is slow, but order of things will likely be the same)
Now I saw that John's code uses codes set as RGB. I really expect it to be slower, so I checked
Interesting, it looks like LB is faster with RGB then with named colors!
I end up with 16218 ms
Next thing was to add "discard" after each scanline.
This is LB "thing" - drawing commands are stored and could be replayed
But storing them takes memory - and time
You see, 300+ lines by 300+ points, each needs two commands (color and set) - that uses quite a lot of memory and pretty visibly slows things down
So we get like this
and got drawing time to 10125 ms
Really, not bad
But I think John's code will not get much from this trick because it draws 40x40 pixels, not 300x300
(but next tests will be with "discard" between loops)
Next idea is to set color once, make one pass with this color, change color and make second pass.
This got drawing time to 7907 ms
Now, pretty last idea is to utilize information
Instead of two passes we first fill area with back color - than change only needed pixels with single pass!
So this halves the time, and I got to 4078 ms.
That's probably all that could be applied to initial program.
Of course there is possibility to put pixels right into BMP file
(and I just did that, and got 2375 ms) ,
- but putting pixels from array to BMP 1:1 is one thing,
and drawing a point of different SIZE is quite another task.
Results (times are fluctuating between runs)
libertybasiccom.proboards.com/thread/1446/3d-arrays-lb4s-dimensions
It's nice and clean and while reading makes perfect sense.
But it is said to be kinda slow
I enabled mainwin and saw it takes most of the time drawing points.
So I went and looked into it
Basically, drawing part is this
for y =N -1 to 0 step -1
for z =0 to N -1
v$ =arrayGet$( x, y, z)
'if v$ ="0 0 0" then #wg "size 2" else #wg "size 4"
#wg "color "; v$
#wg "backcolor "; v$
#wg "set "; 440 +10 *y; " "; 500 -10 *z
scan
next z
You see, for each color we set color value - issue "color" command - and LB has to execute it
(and it looks like
#wg "backcolor "; v$
command has no use at all - likely leftover from other versions)From other parts of code it looks like currently there only 2 colors used (actually second is background color)
I start wondering how much it takes and how fast we can get?
So here's a test
I open normal "for graphics_nsb_nf" window, it happen to be 312x322 points
Randomly filled 312x322 array with 0 or 1
and tried to plot 1 with red, 0 with blue
First attempt was just that
if e(i,j) then #gr "color red; set ";i; " ";j else #gr "color blue; set ";i; " ";j
It ended up at 17000 ms (my machine is slow, but order of things will likely be the same)
Now I saw that John's code uses codes set as RGB. I really expect it to be slower, so I checked
if e(i,j) then #gr "color 255 0 0; set ";i; " ";j else #gr "color 0 0 255; set ";i; " ";j
Interesting, it looks like LB is faster with RGB then with named colors!
I end up with 16218 ms
Next thing was to add "discard" after each scanline.
This is LB "thing" - drawing commands are stored and could be replayed
But storing them takes memory - and time
You see, 300+ lines by 300+ points, each needs two commands (color and set) - that uses quite a lot of memory and pretty visibly slows things down
So we get like this
for i = 1 to 2*cx
scan
#gr "discard"
for j = 1 to 2*cy
if e(i,j) then #gr "color 255 0 0; set ";i; " ";j else #gr "color 0 0 255; set ";i; " ";j
next
next
and got drawing time to 10125 ms
Really, not bad
But I think John's code will not get much from this trick because it draws 40x40 pixels, not 300x300
(but next tests will be with "discard" between loops)
Next idea is to set color once, make one pass with this color, change color and make second pass.
This got drawing time to 7907 ms
Now, pretty last idea is to utilize information
there only 2 colors used (actually second is background color)
Instead of two passes we first fill area with back color - than change only needed pixels with single pass!
So this halves the time, and I got to 4078 ms.
That's probably all that could be applied to initial program.
Of course there is possibility to put pixels right into BMP file
(and I just did that, and got 2375 ms) ,
- but putting pixels from array to BMP 1:1 is one thing,
and drawing a point of different SIZE is quite another task.
Results (times are fluctuating between runs)
area is 312x322 points
Time generating data 1860
Time drawing with colors set each time 11390
Time drawing with colors as RGB 10094
Time drawing with 2 passes 7969
Time drawing with fill red, plot blue 4265
Time writing to BMP 2047
open "test" for graphics_nsb_nf as #gr
#gr "trapclose [quit]"
#gr "home; down; posxy cx cy"
dim e(2*cx, 2*cy)
print "area is ";2*cx;"x";2*cy; " points"
t0=time$("ms")
for i = 1 to 2*cx
scan
for j = 1 to 2*cy
e(i,j) = rnd(0)>.5
next
next
t1=time$("ms")
print "Time generating data ";t1-t0
'goto [skip]
'drawing data setting colors
for i = 1 to 2*cx
scan
#gr "discard"
for j = 1 to 2*cy
if e(i,j) then #gr "color red; set ";i; " ";j else #gr "color blue; set ";i; " ";j
next
next
t2=time$("ms")
print "Time drawing with colors set each time ";t2-t1
'drawing data setting colors as RGB
#gr "cls" 'should discard memory as well?
t2=time$("ms")
for i = 1 to 2*cx
scan
#gr "discard"
for j = 1 to 2*cy
if e(i,j) then #gr "color 255 0 0; set ";i; " ";j else #gr "color 0 0 255; set ";i; " ";j
next
next
t3=time$("ms")
print "Time drawing with colors as RGB ";t3-t2
'drawing data setting colors once, 2 passes
#gr "cls"
t3=time$("ms")
#gr "color red"
for i = 1 to 2*cx
scan
#gr "discard"
for j = 1 to 2*cy
if e(i,j) then #gr "set ";i; " ";j
next
next
#gr "color blue"
for i = 1 to 2*cx
scan
#gr "discard"
for j = 1 to 2*cy
if e(i,j)=0 then #gr "set ";i; " ";j
next
next
t4=time$("ms")
print "Time drawing with 2 passes ";t4-t3
'of cource if other color is empty
'it likely could be filled with boxfilled etc
'cutting half of the time
#gr "cls"
t4=time$("ms")
#gr "fill red"
#gr "color blue"
for i = 1 to 2*cx
scan
#gr "discard"
for j = 1 to 2*cy
if e(i,j)=0 then #gr "set ";i; " ";j
next
next
[skip]
t5=time$("ms")
print "Time drawing with fill red, plot blue ";t5-t4
'now try to writi right to BMP then read back
' make empty BMP
#gr "cls"
#gr "getbmp scr 1 1 ";2*cx;" ";2*cy
fname$="tmp$$$.bmp"
bmpsave "scr", fname$
'I think it's BGR0
colRed$ = chr$(0)+chr$(0)+chr$(255)+chr$(0)
colGreen$ = chr$(0)+chr$(255)+chr$(0)+chr$(0)
colBlue$ = chr$(255)+chr$(0)+chr$(0)+chr$(0)
colBlack$ = chr$(0)+chr$(0)+chr$(0)+chr$(0)
open fname$ for binary as #1
seek #1, 66 'from 0, from 1 would be 67
'lines by Y, upside-down
for j = 2*cy to 1 step -1
scan
for i = 1 to 2*cx
if e(i,j) then print #1, colRed$ else print #1, colBlue$
'if e(i,j) then print #1, colGreen$ else print #1, colBlack$
next
next
close #1
t6=time$("ms")
print "Time writing to BMP ";t6-t5
loadbmp "scr", fname$
#gr "drawbmp scr 1 1 "
wait
[quit]
close #gr
end