Forum Index
HomeZBasic Home   Forum RulesForum Rules   Forum FAQForum FAQ   MemberlistMemberlist   UsergroupsUsergroups   RSS FeedRSS Feed
Site SearchSite Search   LinksLinks   DownloadDownload   Digests and SubscriptionsDigests and Subscriptions
ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in   RegisterRegister
ZBasic code size 20% of BasicX size

 
Post new topic   Reply to topic    Forum Index -> ZBasic Language
Author Message
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 13 December 2005, 6:42 AM    Post subject: ZBasic code size 20% of BasicX size Reply with quote

Some of you may have seen my responses to Tom Becker's "code challenge" on the BasicX board. The difference in code size between BasicX and ZBasic in this particular example was larger than I expected.

Shown below is the second iteration of my solution that incorporates parts of other solutions. The purpose of the function is to return a string with the current time encoded as HHMMSShh for hours, minutes, seconds and hundredths of a second.

The total code size when compiled by ZBasic is 257 bytes compared to 1332 bytes for BasicX. I have seen other examples where the ZBasic code was 60% of the BasicX code. I expect that a difference in that range is probably going to be more typical but it was interesting, nonetheless, to see such a large difference in this one case.

It is also interesting that the code can be modified slightly, using special features of ZBasic to reduce the code size even farther - down to 239 bytes. The ZBasic-specific code is shown below after the original code.

Code:
Sub Main()
   Debug.Print readClock2()
End Sub

Function readClock2() as String
   Dim tstr as String * 8
   Dim lwork as Long
   Dim v as Byte
   Dim addr as Integer

   addr = MemAddress(tstr)
   lWork = Register.RTCtick 'read clock

   ' calculate the hundredths
   v = CByte((lWork * 100 Mod 51200 + 256) \ 512)
   Call RamPoke(v \ 10 Or &H30, addr + 6)
   Call RamPoke(v Mod 10 Or &H30, addr + 7)

   lWork = lWork \ 512 'discard fraction

   ' produce the seconds digits
   v = CByte(lWork Mod 60)
   Call RamPoke(v \ 10 Or &H30, addr + 4)
   Call RamPoke(v Mod 10 Or &H30, addr + 5)

   ' generate the minutes digits
   v = CByte(lWork \ 60 Mod 60)
   Call RamPoke(v \ 10 Or &H30, addr + 2)
   Call RamPoke(v Mod 10 Or &H30, addr + 3)

   ' generate the hours digits
   v = CByte(lWork \ 3600 Mod 24)
   Call RamPoke(v \ 10 Or &H30, addr + 0)
   Call RamPoke(v Mod 10 Or &H30, addr + 1)
   readClock2 = tstr
End Function


Here is the ZBasic-specific code. The only change was to use a byte array to hold the characters as they are generated and then call MakeString() at the end.

Code:
Sub Main()
   Debug.Print readClock2()
End Sub

Function readClock2() as String
   Dim tstr(1 to 8) as Byte
   Dim lwork as Long
   Dim v as Byte

   lWork = Register.RTCtick 'read clock

   ' calculate the hundredths
   v = CByte((LoWord(lWork) * 100 Mod 51200 + 256) \ 512)
   tstr(7) = v \ 10 Or &H30
   tstr(8) = v Mod 10 Or &H30

   lWork = lWork \ 512 'discard fraction

   ' produce the seconds digits
   v = CByte(lWork Mod 60)
   tstr(5) = v \ 10 Or &H30
   tstr(6) = v Mod 10 Or &H30

   ' generate the minutes digits
   v = CByte(lWork \ 60 Mod 60)
   tstr(3) = v \ 10 Or &H30
   tstr(4) = v Mod 10 Or &H30

   ' generate the hours digits
   v = CByte(lWork \ 3600 Mod 24)
   tstr(1) = v \ 10 Or &H30
   tstr(2) = v Mod 10 Or &H30
   readClock2 = MakeString(tstr.DataAddress, SizeOf(tstr))
End Function
Back to top
mikep



Joined: 24 Sep 2005
Posts: 765
Location: Austin, TX

Posted: 13 December 2005, 7:09 AM    Post subject: Reply with quote

Yes this is a very significant shrinkage in the codesize mainly due to the fact that Debug.Print and support code is implemented as a system function in ZBasic rather than as a set of inline BasicX virtual machine code.

A better comparison is for the readClock2 function which is 293 bytes long for BasicX and is 208 bytes long for ZBasic. This code size reduction is more inline with the expected average.

The stack usage for BasicX according to bXDism (http://home.austin.rr.com/perks/micros/bxDism/) is 25 bytes. Is there an equivalent program yet for ZBasic? It would be nice to build this functionality into the compiler/IDE.
Back to top
spamiam



Joined: 13 Nov 2005
Posts: 664

Posted: 13 December 2005, 13:32 PM    Post subject: Reply with quote

mikep wrote:
A better comparison is for the readClock2 function which is 293 bytes long for BasicX and is 208 bytes long for ZBasic.


Almost as important, I wonder what the speed difference is!

-T
Back to top
spamiam



Joined: 13 Nov 2005
Posts: 664

Posted: 13 December 2005, 16:51 PM    Post subject: Reply with quote

Another question on this topic.

You used MakeString() to convert the ascii array to a string. Could this be improved?

Would it be faster to take the string itself, maybe even aliasing the bytes (IF you can alias a string), and then set the ascii characters that way, then set the control bytes to the appropriate values? Since the time stamp is a fixed length, you will KNOW the control byte values.

If a BoundedString were used, then maybe the control bytes are already set and would not require modification.

Quite possibly the MakeString() is so efficient that it can not be improved upon... Especially if you then lose dynamic allocation of the string. Dynamic allocation may not be that useful for a known fixed length string. I forget if dynamic allocation improves on stack consumption.

-Tony
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 13 December 2005, 18:44 PM    Post subject: Reply with quote

Quote:
You used MakeString() to convert the ascii array to a string. Could this be improved?


The original code populated a fixed-length string. This eliminates the code that would normally be needed to set the string length. That works in this case because the returned string is always the same length.

It turns out that it requires less code to populate a byte array and then use MakeString() to create the string to return. A string returned by a function is always a dynamically allocated string. It is a special type of string that is marked as a temporary string. This is necessary because it may be used transiently in an expression and the string pool memory that it uses needs to be freed. If the temporary string is assigned to a string variable it is converted to a normal allocated string if the variable is a dynamically allocated string or the string's characters are copied to the string variable if it is a bounded string, fixed-length string or BasicX statically allocated string.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    Forum Index -> ZBasic Language Time synchro. with the server - Timezone/DST with your computer
Page 1 of 1

 


All content Copyright © 2005-2012 Elba Corp. All Rights Reserved.
Opinions expressed in posts are those of the author and not necessarily those of Elba Corp.
Powered by phpBB © 2001, 2005 phpBB Group