VPOKE() vs PRINT

ページ 1/2
| 2

By Underscore

Rookie (22)

Underscore さんの画像

04-11-2019, 11:49

Hi.

While programming something for MSX1 under blueMSX, noticed how something like

is slower than

by a very noticeable margin.
(I forgot SCREEN 1 in the 1st example)
Even when the PRINT version is using 2 IFs, it is much faster.

I would like to know the reason behind that.

Also I came up with a question:

under MSX-BASIC, what is the fastest way to draw one character on screen at a specific coordinate and also in a sequential way? (specifically, screen 1 if that matters)
Or, is there any way to make the vpoke() version i mentioned, much faster? Besides tricks like defint, and the like,

Thanks

ログイン/登録して投稿

By Grauw

Ascended (10768)

Grauw さんの画像

04-11-2019, 11:54

One thing I notice is that you’re doing an extra addition in the first listing. What if you initialise I to 6145 and loop until it reaches 6912? (Btw, why not use FOR?)

By NYYRIKKI

Enlighted (6067)

NYYRIKKI さんの画像

04-11-2019, 13:14

Yes, the tests are not exactly doing same thing and therefore can't be compared, but the question behind is good anyway.
Even if you do a test where only difference is the PRINT vs. VPOKE you will see that in this kind of case PRINT-version is slightly faster.

The difference comes from the floating point handling... In this case you do complex 6144+I floating point addition and then this value needs to be converted to integer for VPOKE-command. (Please note: Unlike the subject suggests VPEEK() is function, but VPOKE is command)

After you change the I to integer and remove the addition then speed is practically same. As long as it needs to do floating point to integer conversion it will always lose speed, so PRINT that does not handle numbers at all will outperform the VPOKE. MSX-BASIC does floating point mantissa and exponent in base-10 format that has been criticized for being slow already from beginning of 80's.

By thegeps

Paragon (1189)

thegeps さんの画像

04-11-2019, 13:29

Print is faster. The reason is the basic interpreter. Locate x,y: print"yourstring"is the fastest way to print something in the screen1. If you have to print consecutive data you have a third choice, faster than vpoke but slower than print. I tried this way too, looking for faster basic print routine. You can use out instruction, exactly as in assembly coding:
10 screen1:width32:keyoff:cls
20 out &h99,0: out &h99,88
30 fork%=0to767
40 out &h98,65
50 next

You have to send vram addrrss to the port &h99, first the low byte and then hi byte or 64 (so 24*256=6144 and 24 or 64=88): then you send data to print to port &h98. The address auto increments

By Grauw

Ascended (10768)

Grauw さんの画像

04-11-2019, 13:59

NYYRIKKI wrote:

After you change the I to integer

So try again with DEFINT A-Z on line 0 Smile.

By Mortimer

Rookie (20)

Mortimer さんの画像

04-11-2019, 20:58

thegeps wrote:

Print is faster. The reason is the basic interpreter. Locate x,y: print"yourstring"is the fastest way to print something in the screen1. If you have to print consecutive data you have a third choice, faster than vpoke but slower than print. I tried this way too, looking for faster basic print routine. You can use out instruction, exactly as in assembly coding:
10 screen1:width32:keyoff:cls
20 out &h99,0: out &h99,88
30 fork%=0to767
40 out &h98,65
50 next

You have to send vram addrrss to the port &h99, first the low byte and then hi byte or 64 (so 24*256=6144 and 24 or 64=88): then you send data to print to port &h98. The address auto increments

In this way, what would happen if an interruption is triggered between the two outs that set the vram pointer?
It may be unlikely, but it can cause problems. ..

By DanySoft

Champion (452)

DanySoft さんの画像

04-11-2019, 21:14

Try this....

10 defint a-z
20 out &H99,0:out &H99,88
30 time=0
40 for k%=0 to 767
50 out &H98,65
60 next k%
70 a=time:locate 0,0:print a;"second!"

And go this command !

CALL RUN
Ok
Result: 2 second !

CALL RUN, is part of CALL TURBO ON/OFF
Byebye
DanySoft Big smile

By thegeps

Paragon (1189)

thegeps さんの画像

04-11-2019, 23:10

Nothing happen, 'cause you are in basic. Interrupts are triggered a lot between instruction. I tried the code I wrote here...
By the way, today I did a lot of tries. When you use intergers (definta-z or single declaration for each variable or constant like a%) vpoke os faster than locate/print. In detail:
vpoke addr,val is faster than locate x,y: print "A" (print one char)
Vpoke addr,val:vpoke addr,val is faster than locate x,y: print"AA" (print of 2 chars)
3x vpoke,val is faster than locatex,y: print"AAA" (print of 3 chars)
4x vpoke is faster than locate x,y: print"AAAA" (print of 4 chars)
5x vpoke is equal to locatex,y; print"AAAAA" (print of 5 chars)
From 6x vpoke and on, vpoke usage is slower than locatex,y: print"AAAAAA" and more

By Underscore

Rookie (22)

Underscore さんの画像

09-11-2019, 02:55

I tested different methods using your suggestions:


Runs in 107 cycles (slightly faster if using "NEXT" instead of "NEXT I%")


Runs in 107 cycles


Runs in 119 cycles

By zett

Hero (608)

zett さんの画像

09-11-2019, 09:36

cool msx basic speed runs

By jltursan

Prophet (2619)

jltursan さんの画像

09-11-2019, 12:27

And if you join the three lines, FOR, VPOKE & NEXT in the same line you can get the last optimization. No idea if it'll be noticeable but worth trying it

ページ 1/2
| 2