Author Topic: Benchmark time!  (Read 5281 times)

0 Members and 1 Guest are viewing this topic.

Brian Alvarez

  • Guest
Benchmark time!
« on: June 02, 2019, 10:20:20 PM »
 PluriBASIC now can compile whatever code i throw at it (within supported statements), so,
i figured it was time for benchmarks!

Surprisingl Oxygen beats PowerBASIC's speed comparing regular string and wstring....

Code: [Select]
#COMPILE EXE
#COMPILER pbwin
#OPTIONS X32 CONSOLE
#DIM ALL

Macro compare(DT1, SZ1, DT2, SZ2)
    MACROTEMP i, T1, T2, C1, C2, SU, SA

    LOCAL i AS LONG
   
    LOCAL SU AS DT1 sz1 
    LOCAL SA AS DT2 sz2
   
    SU = "compare1"
    SA = "compare2"
   
    LOCAL t1 AS SINGLE
    LOCAL t2 AS SINGLE
    LOCAL c1  AS LONG
    LOCAL c2  AS LONG
   
    t1 = timer
   
    for i = 1 to 1000000
        IF SU = SU THEN           
            incr c1
        END IF
        IF SU <> SA THEN           
            incr c2
        END IF       
    next
   
    t2 = timer
   
    stdout str$(t2-t1, 6) & "    equal: " & STR$(C1) & "  different: " & str$(C2)

end macro

FUNCTION PBMAIN() AS LONG

    stdout EXE.compiler$ & " benchmark for string comparison!"
   
    compare(string,,wstring,)
    compare(string,,wstring, * 20)
    compare(string, * 20,wstring,)
    compare(string, * 20,string, * 20)
    compare(wstring, * 20,wstring, * 20)

END FUNCTION

Code: [Select]
PowerBASIC for Windows benchmark for string comparison!
 .208984    equal:  1000000  different:  1000000
 .292969    equal:  1000000  different:  1000000
 .522034    equal:  1000000  different:  1000000
 .427002    equal:  1000000  different:  1000000
 .42804    equal:  1000000  different:  1000000

Code: [Select]
OxygenBASIC benchmark for string comparison!
0.15625    equal:  1000000  different:  1000000
0.15625    equal:  1000000  different:  1000000
0.5937    equal:  1000000  different:  1000000
0.62502    equal:  1000000  different:  1000000
0.53022    equal:  1000000  different:  1000000

Brian Alvarez

  • Guest
Re: Benchmark time!
« Reply #1 on: June 02, 2019, 11:33:13 PM »
 These are the results of comparing strings of the same type:

Code: [Select]
    compare(string,,string,)
    compare(wstring,,wstring,)

Code: [Select]
PowerBASIC for Windows benchmark for string comparison!
 .078125    equal:  1000000  different:  1000000
 8.30078E-2    equal:  1000000  different:  1000000

Code: [Select]
OxygenBASIC benchmark for string comparison!
0.0625    equal:  1000000  different:  1000000
0.4375    equal:  1000000  different:  1000000

Mike Lobanovsky

  • Guest
Re: Benchmark time!
« Reply #2 on: June 03, 2019, 03:59:25 AM »
Oh, that's quite impressive, isn't it?

BTW what about executable file sizes you compiled for the benchmark? Can we have them to test on our boxes as well?

Brian Alvarez

  • Guest
Re: Benchmark time!
« Reply #3 on: June 03, 2019, 12:03:38 PM »
Hello Mike. Sure, i am preparing a more complete and comprehensive test, i will post all when im done.

Brian Alvarez

  • Guest
Re: Benchmark time!
« Reply #4 on: June 03, 2019, 12:34:37 PM »
Heres the new tester:

Code: [Select]
#COMPILE EXE
#COMPILER oxygen
#OPTIONS X32 CONSOLE
#DIM ALL

Macro compare(DT1, SZ1, DT2, SZ2)
    MACROTEMP i, T1, T2, C1, C2, SU, SA

    LOCAL i AS LONG
       
    LOCAL SU AS DT1 sz1 
    LOCAL SA AS DT2 sz2
   
    SU = "compare1"
    SA = "compare2"
   
    LOCAL t1 AS SINGLE
    LOCAL t2 AS SINGLE
    LOCAL c1  AS LONG
    LOCAL c2  AS LONG
   
    t1 = timer
   
    for i = 1 to 1000000
        IF SU = SU THEN           
            incr c1
        END IF
        IF SU <> SA THEN           
            incr c2
        END IF       
    next
    t2 = timer
   
    ' The PluriBASIC ide reads console as it is sent, so, to avoid unwanted line breaks,
    ' we send everything in one line.
    stdout iif$((C1=1000000) and (C2=1000000), "*OK!* ", "ERROR ") & _
           format$(t2-t1, "0.000") & "  " & _
           typename(SU) & _               
           iif$(typesize(SU), " *" & str$(typesize(SU)), "") & _
           " vs " & typename(SA) &  _
           iif$(typesize(SA), " *" & str$(typesize(SA)), "") & _
           "  "
           
end macro

FUNCTION PBMAIN() AS LONG
    stdout EXE.compiler$ & " benchmark for string comparison! (" & str$(exe.architecture) & "bits)"
    stdout   
    compare(string,,string,)
    compare(wstring,,wstring,)
    compare(string,,wstring,)
    compare(string,,asciiz, * 20)
    compare(string,,Wstring, * 20)
    compare(string, * 20,wstring,)
    compare(string, * 20,string, * 20)
    compare(string, * 20,asciiz, * 20)
    compare(string, * 20,string, * 20)
    compare(wstring, * 20,wstring, * 20)
    compare(wstring, * 20,asciiz, * 20)
    compare(asciiz, * 20,asciiz, * 20)

END FUNCTION

Compilation times and sizes:

Code: [Select]
PluriBASIC 6.0.236421.0 for Windows, Copyright © 2010-2019 PluriBASIC® Inc.
PowerBASIC for Windows, Copyright (c) 1996-2019 PowerBasic Inc.

    Primary source: C:\Users\Diamante\Documents\PluriBASIC\Clean\COMPARISON.BAS {78 total lines}
 Target conversion: COMPARISON.exe (32 bits)
   Conversion time: 0.1410 seconds, at 33,191 lines/minute.
  Compilation time: 0.1220 seconds, at 193,278 lines/minute.
    Generated code: 8.95 kb
  Embedded objects: 47 bytes
      Support code: 1.14 kb
        Other code: 69 bytes
------------------------------------
       Source size: 10.20 kb
     Compiled size: 25.50 kb

Code: [Select]
PluriBASIC 6.0.236421.0 for Windows, Copyright © 2010-2019 PluriBASIC® Inc.
Oxygen Basic for Windows, Copyright © 2010-2019, Charles E V Pegge.

    Primary source: C:\Users\Diamante\Documents\PluriBASIC\Clean\COMPARISON.BAS {78 total lines}
 Target conversion: COMPARISON.exe (32 bits)
   Conversion time: 0.0780 seconds, at 60,000 lines/minute.
  Compilation time: 0.8840 seconds, at 60,203 lines/minute.
    Generated code: 8.26 kb
  Embedded objects: 0 bytes
      Support code: 12.65 kb
        Other code: 36 bytes
------------------------------------
       Source size: 20.95 kb
     Compiled size: 40.50 kb

Code: [Select]
PluriBASIC 6.0.236421.0 for Windows, Copyright © 2010-2019 PluriBASIC® Inc.
Oxygen Basic for Windows, Copyright © 2010-2019, Charles E V Pegge.

    Primary source: C:\Users\Diamante\Documents\PluriBASIC\Clean\COMPARISON.BAS {78 total lines}
 Target conversion: COMPARISON.exe (64 bits)
   Conversion time: 0.0930 seconds, at 50,322 lines/minute.
  Compilation time: 0.9960 seconds, at 53,433 lines/minute.
    Generated code: 8.26 kb
  Embedded objects: 0 bytes
      Support code: 12.65 kb
        Other code: 36 bytes
------------------------------------
       Source size: 20.95 kb
     Compiled size: 53.00 kb

Benchmark results:

Code: [Select]
PowerBASIC for Windows benchmark for string comparison! ( 32bits)

*OK!* 0.082  STRING vs STRING 
*OK!* 0.082  WSTRING vs WSTRING 
*OK!* 0.203  STRING vs WSTRING 
*OK!* 0.184  STRING vs ASCIIZ * 20 
*OK!* 0.289  STRING vs WSTRING * 20 
*OK!* 0.500  STRING * 20 vs WSTRING 
*OK!* 0.430  STRING * 20 vs STRING * 20 
*OK!* 0.445  STRING * 20 vs ASCIIZ * 20 
*OK!* 0.402  STRING * 20 vs STRING * 20 
*OK!* 0.410  WSTRING * 20 vs WSTRING * 20 
*OK!* 0.594  WSTRING * 20 vs ASCIIZ * 20 
*OK!* 0.504  ASCIIZ * 20 vs ASCIIZ * 20 


Code: [Select]
OxygenBASIC benchmark for string comparison! (32bits)

*OK!* 0.0944  STRING vs STRING 
*OK!* 0.5311  WSTRING vs WSTRING 
*OK!* 0.1255  STRING vs WSTRING 
*OK!* 0.1566  STRING vs ASCIIZ *20 
*OK!* 0.1877  STRING vs WSTRING *20 
*OK!* 0.5311  STRING *20 vs WSTRING 
*OK!* 0.5622  STRING *20 vs STRING *20 
*OK!* 0.6255  STRING *20 vs ASCIIZ *20 
*OK!* 0.6255  STRING *20 vs STRING *20 
*OK!* 0.5311  WSTRING *20 vs WSTRING *20 
*OK!* 0.5311  WSTRING *20 vs ASCIIZ *20 
*OK!* 0.4699  ASCIIZ *20 vs ASCIIZ *20 

Code: [Select]
OxygenBASIC benchmark for string comparison! (64bits)

*OK!* 0.0622  STRING vs STRING 
*OK!* 0.3122  WSTRING vs WSTRING 
*OK!* 0.0944  STRING vs WSTRING 
*OK!* 0.1255  STRING vs ASCIIZ *20 
*OK!* 0.1566  STRING vs WSTRING *20 
*OK!* 0.4066  STRING *20 vs WSTRING 
*OK!* 0.4377  STRING *20 vs STRING *20 
*OK!* 0.4699  STRING *20 vs ASCIIZ *20 
*OK!* 0.4377  STRING *20 vs STRING *20 
*OK!* 0.4066  WSTRING *20 vs WSTRING *20 
*OK!* 0.4066  WSTRING *20 vs ASCIIZ *20 
*OK!* 0.3444  ASCIIZ *20 vs ASCIIZ *20


Executables are attached. Please ignore some formatting errors for exygen compilations, i am working in STR.

Mike Lobanovsky

  • Guest
Re: Benchmark time!
« Reply #5 on: June 04, 2019, 04:35:29 AM »
Hi Brian,

Thanks for walking an extra mile with the binaries!

Generally, the test shows high compatibility of O2 with PB, both speed- and size-wise. I'm sure Charles The Almighty will find ways and means to handle his STRINGs just a tad faster to put PB to bed for good. :D

Below please find a snapshot of my results (my box specs are in my signature) and a repackaged zip with the binaries hacked to run natively in your consoles to be able to inspect the results more conveniently.

Brian Alvarez

  • Guest
Re: Benchmark time!
« Reply #6 on: June 04, 2019, 03:15:50 PM »
 Some of the speed compromises may not be entirely Oxygen's responsability. For example, PluriBASIC is converting WSTRING to STRING even if both strings to compare are WSTRING. Il tweak my engine, hopefully i can get rid of unrequired conversions....


Mike Lobanovsky

  • Guest
Re: Benchmark time!
« Reply #7 on: June 05, 2019, 09:27:46 AM »
Re. file sizes, if much of PluriBASIC-to-O2 innards is implemented using O2 in-place macros rather than functions, the Oxygen binary, alas, is bound to always be fatter than PowerBASIC.

Brian Alvarez

  • Guest
Re: Benchmark time!
« Reply #8 on: June 05, 2019, 11:48:42 PM »
I know... but it is a price I had to pay when not knowing the datatypes. Fortunately there are cases where i know. I will make those functions instead of macros.

 By the way, when switching to the correct data-types, comparing WSTRING vs WSTRING without conversions, the times tripled...  :o

Im switching back to strings...  ;D

Mike Lobanovsky

  • Guest
Re: Benchmark time!
« Reply #9 on: June 06, 2019, 01:22:26 AM »
And Brian,

Please don't hesitate to provide more precompiled binaries whenever possible for us to be able to take a more active part in O2 vs PB comparison tests, too. Personally, I'm very fond of benchmarking everything I can lay my hands on. ;)

In case you don't have access to PB/CC to precompile native console PB versions, you may just use any hex editor to manually change the byte at hex offset 0x125 (&H125 BASIC-style) from value 02 (Win32 GUI subsystem) to value 03 (Win32 CUI subsystem). For O2 binaries, the byte offset is 0x144 in both 32 and 64 bits.

That's how I hacked the binaries you submitted, to be able to run them by dragging-and-dropping them into a common system console and read the results in there rather than catch a glimpse of their own consoles that implode before we're able to make out anything.

Brian Alvarez

  • Guest
Re: Benchmark time!
« Reply #10 on: June 06, 2019, 01:28:08 AM »
 WOA!! Take a look at this guys! Oxygen blows PowerBASIC away adding this twist!!!  :o :o :o
I made the test do a concatenation besides just comparing the strings... look at the times!!  :o

 I kinda refuse to believe it... i will make more tests tomorrow, as its 3:23 right now here.  ;D

Code: [Select]
#COMPILE EXE
#COMPILER PBWIN
#OPTIONS X32 CONSOLE
#DIM ALL

Macro compare(DT1, SZ1, DT2, SZ2)
    MACROTEMP i, T1, T2, C1, C2, SB, SU, SA

    LOCAL i AS LONG
       
    LOCAL SB AS DT1 sz1 
    LOCAL SU AS DT1 sz1 
    LOCAL SA AS DT2 sz2
    LOCAL t1 AS SINGLE
    LOCAL t2 AS SINGLE
    LOCAL c1 AS LONG
    LOCAL c2 AS LONG   
   
    SB = "concat"
    SU = "compare1"
    SA = "compare2"
   
    t1 = timer
   
    for i = 1 to 1000000
        IF SB + SU = SB + SU THEN           
            incr c1
        END IF
        IF SB + SU <> SB + SA THEN           
            incr c2
        END IF       
    next
   
    t2 = timer
   
    ' The PluriBASIC ide reads console as it is sent, so, to avoid unwanted line breaks,
    ' we send everything in one line.
    stdout iif$((C1=1000000) and (C2=1000000), "*OK!* ", "ERROR ") & _
           format$(t2-t1, "0.000") & "  " & _
           typename(SU) & _               
           iif$(typesize(SU), " *" & str$(typesize(SU)), "") & _
           " vs " & typename(SA) &  _
           iif$(typesize(SA), " *" & str$(typesize(SA)), "") & _
           "  "
           
end macro

FUNCTION PBMAIN() AS LONG
    stdout EXE.compiler$ & " benchmark for string comparison! (" & str$(exe.architecture) & "bits)"
    stdout   
    compare(string,,string,)
    compare(wstring,,wstring,)
    compare(string,,wstring,)
    compare(string,,asciiz, * 20)
    compare(string,,Wstring, * 20)
    compare(string, * 20,wstring,)
    compare(string, * 20,asciiz, * 20)
    compare(string, * 20,string, * 20)
    compare(wstring, * 20,wstring, * 20)
    compare(wstring, * 20,asciiz, * 20)
    compare(asciiz, * 20,asciiz, * 20)

END FUNCTION


Code: [Select]
OxygenBASIC benchmark for string comparison! (64bits)

*OK!* 0.406  STRING vs STRING 
*OK!* 0.391  WSTRING vs WSTRING 
*OK!* 0.391  STRING vs WSTRING 
*OK!* 0.391  STRING vs ASCIIZ *20 
*OK!* 0.422  STRING vs WSTRING *20 
*OK!* 0.687  STRING *20 vs WSTRING 
*OK!* 0.703  STRING *20 vs ASCIIZ *20 
*OK!* 0.687  STRING *20 vs STRING *20 
*OK!* 0.664  WSTRING *20 vs WSTRING *20 
*OK!* 0.672  WSTRING *20 vs ASCIIZ *20 
*OK!* 0.405  ASCIIZ *20 vs ASCIIZ *20 

Code: [Select]
OxygenBASIC benchmark for string comparison! ( 32bits)

*OK!* 0.523  STRING vs STRING 
*OK!* 0.516  WSTRING vs WSTRING 
*OK!* 0.547  STRING vs WSTRING 
*OK!* 0.609  STRING vs ASCIIZ * 20 
*OK!* 0.562  STRING vs WSTRING * 20 
*OK!* 0.844  STRING * 20 vs WSTRING 
*OK!* 0.844  STRING * 20 vs ASCIIZ * 20 
*OK!* 0.802  STRING * 20 vs STRING * 20 
*OK!* 0.781  WSTRING * 20 vs WSTRING * 20 
*OK!* 0.781  WSTRING * 20 vs ASCIIZ * 20 
*OK!* 0.594  ASCIIZ * 20 vs ASCIIZ * 20 


Code: [Select]
PowerBASIC for Windows benchmark for string comparison! ( 32bits)

*OK!* 0.542  STRING vs STRING 
*OK!* 0.540  WSTRING vs WSTRING 
*OK!* 0.799  STRING vs WSTRING 
*OK!* 0.604  STRING vs ASCIIZ * 20 
*OK!* 0.892  STRING vs WSTRING * 20 
*OK!* 1.465  STRING * 20 vs WSTRING 
*OK!* 1.167  STRING * 20 vs ASCIIZ * 20 
*OK!* 1.129  STRING * 20 vs STRING * 20 
*OK!* 1.344  WSTRING * 20 vs WSTRING * 20 
*OK!* 1.510  WSTRING * 20 vs ASCIIZ * 20 
*OK!* 1.287  ASCIIZ * 20 vs ASCIIZ * 20 



Brian Alvarez

  • Guest
Re: Benchmark time!
« Reply #11 on: June 06, 2019, 01:37:56 AM »
SB is the same string type as SU, this is the code that PluriBASIC is generating for Oxygen and PowerBASIC respectively so you can compile them and benchmark them yourselves!:

Code: [Select]
'Generated with PluriBASIC 6.0.237326.0

$ filename "C:\Users\Diamante\Documents\PluriBASIC\Clean\COMPARISON.exe"

uses rtl32
uses console

DIM STRING ¤SYSTEM_UDT_OFFSETS(0)
STRING ¤TMPS = "" ' a temporary string.
DECLARE FUNCTION ¤GetLastError        Lib "Kernel32.dll" Alias "GetLastError" () AS LONG
DECLARE FUNCTION ¤GetAsyncKeyState    Lib "User32.dll"   Alias "GetAsyncKeyState" (ByVal vKey AS LONG) AS short
DECLARE SUB ¤Sleep                    lib "Kernel32.dll" alias "Sleep" (dword mSec)

function ¤INI_QUAD(dword v1, v2) as quad
    quad v = 0
    copy @v+0, @v2, 4
    copy @v+4, @v1, 4
    return v
end function

DECLARE FUNCTION ¤OpenProcess         Lib "KERNEL32.DLL"  Alias "OpenProcess" (ByVal dwDesiredAccess AS DWORD, ByVal bInheritHandle AS LONG, ByVal dwProcessId AS SYS) AS SYS
DECLARE FUNCTION ¤TerminateProcess    Lib "KERNEL32.DLL"  Alias "TerminateProcess" ( ByVal hProcess AS SYS, ByVal uExitCode AS DWORD) AS LONG
DECLARE FUNCTION ¤CloseHandle         Lib "KERNEL32.DLL"  Alias "CloseHandle" (ByVal hObject AS SYS) AS LONG
DECLARE FUNCTION ¤GetCurrentProcessId Lib "KERNEL32.DLL"  Alias "GetCurrentProcessId" () AS SYS

MACRO ¤SET_ERR(n)
    Err.err = n
    Err.erl = Err.erp
END MACRO

MACRO ¤ONERR(l, e)
   Err.err = e
   IF (Err.err>0) THEN
      Err.ers = Err.erp
      Err.erl = l   
      IF Err.Oe1 THEN
         JMP Err.Oe1
      ELSEIF Err.Oe2 THEN
         CALL Err.Oe2
      END IF
   else
      Err.ers = ""
      Err.erl = 0   
   END IF
END MACRO

MACRO ERRCLEAR
    Err.err = 0
    Err.erl = 0
    Err.ers = ""
END MACRO

CLASS ¤SYSERR
    public sys Oe1 = 0
    public sys Oe2 = 0
    public int err = 0
    public int erl = 0
    public string erp = ""
    public string ers = ""
END CLASS
declare function PluriBASICGetTickCntTimer lib "kernel32.dll" alias "GetTickCount" () as dword
DECLARE FUNCTION ¤WriteConsole     LIB "KERNEL32.DLL" ALIAS "WriteFile" (BYVAL hFile AS SYS, lpBuffer AS ANY, BYVAL nNumberOfBytesToWrite AS dword, lpNumberOfBytesWritten AS dword, lpReserved AS long) AS LONG
DECLARE FUNCTION ¤AllocConsole     LIB "KERNEL32.DLL" ALIAS "AllocConsole" () AS LONG
DECLARE FUNCTION ¤FlushFileBuffers LIB "KERNEL32.DLL" ALIAS "FlushFileBuffers" (BYVAL hFile AS SYS) AS LONG
DECLARE FUNCTION ¤GetStdHandle     LIB "KERNEL32.DLL" Alias "GetStdHandle" (ByVal nStdHandle AS DWORD) AS SYS

' STARTS PLURIBASIC_PREPARE.BIN
' This code is executed before anything else, if you want to do something after defining other things, see PLURIBASIC_INIT

int ¤i = 0
' STARTS SYSTEM_OPERATORS.BIN

FUNCTION ¤BytOvf(byte b) AS byte
    return b
END FUNCTION

FUNCTION ¤STRDIF(STRING a, STRING b) AS INT
   IF (a = b) THEN
       return 0
   else
       return -1
   end if
END FUNCTION

FUNCTION ¤STREQL(STRING a, STRING b) AS INT
   IF (a = b) THEN
       return -1
   else
       return 0
   end if
END FUNCTION

FUNCTION ¤ISTRUE(byval quad v1) AS QUAD   
    IF v1 = 0 then
        return 0
    ELSE
        return -1
    END IF
END FUNCTION

FUNCTION ¤ISFALSE(byval quad v1) AS QUAD
    IF v1 = 0 then
        return -1
    ELSE
        return 0
    END IF
END FUNCTION

FUNCTION ¤NOT(byval quad v1) AS QUAD
    dword w1
    dword w2
    quad r   
    copy @w1, @v1, 4
    copy @w2, @v1+4, 4   
    w1 = not(w1)
    w2 = not(w2)   
    copy @r,   @w1, 4
    copy @r+4, @w2, 4
    return r
END FUNCTION

FUNCTION ¤AND(byval quad v1, v2) as quad
    dword w1
    dword w2
    quad r
    copy @w1, @v1, 4
    copy @w2, @v2, 4   
    w1 = (w1 and w2)   
    copy @r, @w1, 4   
    copy @w1, @v1+4, 4
    copy @w2, @v2+4, 4
    w1 = (w1 and w2)   
    copy @r+4, @w1, 4   
    return r   
end function

FUNCTION ¤OR(byval int v1, v2) as int
    return v1 or v2
end function

'FUNCTION ¤OR(byval quad v1, v2) as quad
'    dword w1
'    dword w2
'    quad r
'    copy @w1, @v1, 4
'    copy @w2, @v2, 4   
'    w1 = (w1 or w2)   
'    copy @r, @w1, 4   
'    copy @w1, @v1+4, 4
'    copy @w2, @v2+4, 4
'    w1 = (w1 or w2)   
'    copy @r+4, @w1, 4   
'    return r   
'end function

FUNCTION ¤IMP(byval quad v1, v2) as quad
    if v1 then return -1
    if v2 then return -1
end function

FUNCTION ¤EQV(byval quad v1, v2) as quad
    if v1=0 then return 0
    if v2=0 then return 0
    return -1
end function

FUNCTION ¤MOD(quad v1, v2) as quad
    return MOD(v1, v2)
end function
' END OF SYSTEM_OPERATORS.BIN
' CONTINUES (12) PLURIBASIC_PREPARE.BIN



#DEF HANDLE SYS






TYPE ¤SYSNMHDR
    hwndFrom AS SYS
    idFrom   AS SYS
    Code     AS DWORD
END TYPE


class ¤SYSF


                             
    FUNCTION CONSTRUCTOR()
    END FUNCTION       
           
END CLASS

new ¤SYSF EXE()


' END OF PLURIBASIC_PREPARE.BIN
' STARTS WSTRING.BIN
//assigns a truncated null terminated string.
MACRO ¤WSTR_SET(v, c, l  b)
    wstring b = c
    if len(b) > l then
        b = left(b, l)
    elseif len(b) < l then
        b += space(l-len(b))
    end if
    v = b       
END MACRO
' END OF WSTRING.BIN
' STARTS TYPESIZE.BIN
' not necessary.


' END OF TYPESIZE.BIN
' STARTS TIMER.BIN

// returns the number of seconds since midnight.
FUNCTION TIMER() AS DOUBLE
    return (PluriBASICGetTickCntTimer() / 1000)
END FUNCTION

' END OF TIMER.BIN
' STARTS STRINGN.BIN
//Assigns a truncated null terminated string.
MACRO ¤STRN_SET(v, c, l  b)   
    string b = c
    if len(b) > l then
        b = left(b, l)
    elseif len(b) < l then
        b += space(l-len(b))
    end if
    v = b               
END MACRO


' END OF STRINGN.BIN
' STARTS STR$.BIN
    'int dp   ' DECIMAL PLACES
    'int trz  ' STRIP TRAILING ZEROS
    'int sn   ' SCIENTIFIC NOTATION BY DEFAULT
    'int sdp  ' INHIBIT ZERO BEFORE DECIMAL POINT
    'int sns  ' LEADING SPACE FOR NON NEGATIVE NUMBERS
    'int lps  ' LEAD PADDING SPACES

    'numberformat(8,0,0,0,1,0) 'default settings

    'numberformat 'return to default
   
MACRO ¤STRCODE(dc)
    numberformat(dc,1,0,1,1,0)
    string ss = str(v)
    numberformat
    return ss
END MACRO


FUNCTION ¤STR(double v, byref long d = 0) as string
    long d2 = 6
    if @d then d2 = d
    ¤STRCODE(d2)
END FUNCTION

FUNCTION ¤STR(single v, byref long d = 0) as string
    long d2 = 6
    if @d then d2 = d
    ¤STRCODE(d2)
END FUNCTION

FUNCTION ¤STR(quad v, byref long d = 0) as string
    ¤STRCODE(0)   
END FUNCTION


' END OF STR$.BIN
' STARTS PRINTR.BIN

SUB ¤INITCONSOLE()
    STATIC Allc AS LONG
    IF Allc=0 THEN
        ¤AllocConsole()
        Allc = 1
    END IF   
END SUB

MACRO ¤STDOUT() 
  INT lWritten = 0     
  SYS hFile    = 0
  INT Btc      = 0 
 
  ¤INITCONSOLE()
 
  if cr=1 then s += chr(13, 10)
  if cr=2 then s += "</br>"     
 
  ¤Sleep(0)
 
  hFile = ¤GetStdHandle(-11)
 
  FOR Btc = 1 TO 50     
     IF ((Btc*32000)-31999) > len(s) THEN EXIT FOR
     TTsnd = MID(s, ((Btc*32000)-31999), 32000)
     ¤WriteConsole(hFile, ByVal StrPtr(TTsnd), byval Len(TTsnd), lWritten, ByVal 0)
  NEXT Btc
 
  '¤FlushFileBuffers(hFile)
 
END MACRO

SUB ¤PRINTASZ(ASCIIZ c[0], byval int cr)
    STRING TTsnd = ""
    string s = c   
    ¤STDOUT()     
END SUB

SUB ¤PRINTSTR(STRING c, byval int cr)
    STRING TTsnd = ""
    STRING s     = c
    ¤STDOUT()     
END SUB

SUB ¤PRINTJSN(STRING c, byval int cr)
    STRING TTsnd = ""
    STRING s     = c
    ¤STDOUT()     
END SUB

SUB ¤PRINTSTZ(ZSTRING c[0], byval int cr)
    STRING TTsnd = ""
    STRING s     = c
    ¤STDOUT()     
END SUB
               
SUB ¤PRINTWST(WSTRING c, byval int cr)
    STRING TTsnd = ""
    STRING s     = c               
    ¤STDOUT()
END SUB

SUB ¤PRINTWSZ(ZSTRING2 c[0], byval int cr)
    WSTRING TTsnd = ""
    WSTRING s     = c       
    ¤STDOUT()     
END SUB

' END OF PRINTR.BIN
' STARTS PLURIBASIC_INIT.BIN
' This code is executed before anything else, if you want to do something before nything else, see PLURIBASIC_PREPARE
' END OF PLURIBASIC_INIT.BIN
' STARTS IIF$.BIN
' Returns a result depending on the condition.
FUNCTION IIF(quad c, string o1, o2) AS STRING
    if c then
        return o1
    else
        return o2
    end if
END FUNCTION

' END OF IIF$.BIN
' STARTS FORMAT$.BIN


FUNCTION ¤FORMATCODE(double dd, byref string f, int decimals) as string

  f += news(3) ' extra space to allow checking.
 
  int  iPeriod  = -1
  int  iCommas  = 0
  int  iDigits  = 0
  int  iPercent = 0
  int  iFill    = 0
  int  i        = 0
  int cm        = 0
  int iBegin    = 0
  int ml        = len(f)-3
  string o      = ""
  int  p[2]
  byte b at strptr(f)
 
  for i = 1 to len(f)
    select case b[i]
        case 44 ' ,
            if iDigits then
                iCommas = 1
                b[i]    = 0                 
            end if
       
        case 42 ' *
            iDigits += 1                   
            if iPeriod != -1 then
                p[2] += 2
            else
                p[1] += 2
            end if       
            iFill   = b[i+1]
            b[i]    = 2             
            b[i+1]  = 2
            i += 1
           
        case 34
            b[i] = 0
            do
                i += 1
                if b[i] = 34 then
                    if b[i+1] != 34 then
                        b[i] = 0
                        exit do
                    end if
                end if               
            loop
           
        case 92 ' \   
            b[i] = 0
            if b[i+1] = 34 then
                if b[i+2] = 34 then
                    b[i+2] = 0
                    i += 2
                else
                    b[i+1] = 0
                    i += 1
                end if
                continue               
            end if
            i += 1
           
        case 48
            iDigits += 1                   
            if iPeriod != -1 then
                p[2] += 1       
                b[i] = 1
            else
                p[1] += 1
                b[i] = 1
            end if
           
        case 35
            iDigits += 1                   
            if iPeriod != -1 then
                p[2] += 1       
                b[i] = 2
            else
                p[1] += 1
                b[i] = 2
            end if           
       
        case 37
            b[i] = 0
            iPercent = 1           
           
        case 46
            if iPeriod = -1 then
                iPeriod  = i
            end if
       
        CASE 32, 36, 38, 40, 41, 43, 45         
            ' these are allowed directly...
           
        case else
            ' anything else is removed.
            b[i] = 0           
       
    end select
  next i
 
  if iPeriod = -1 then
    iBegin = ml
  else
    iBegin = iPeriod
  end if
 
  if iPercent then
    dd = (dd * 100)
  end if   
 
'#IF X64
    ' there is currently a bug for 64 bit compilations.
  string ss = str(dd, p[2])         
'#ELSE
  'numberformat(decimals,1,0,1,1,0)
  'string ss = str(dd)
  'numberformat
'#ENDIF
 
  ' split the real numbers. 
  byte b at strptr(ss)
  string sValue   = "" 
  string sDecimal = ""
   
  for i = 1 to len(ss)
    if b[i] = 46 then
        sValue   = left(ss, i-1)       
        sDecimal = mid(ss, i+1)
        exit for
    elseif i = len(ss) then
        sValue   = ss
        sDecimal = ""
    end if
  next i 
 
'  print ss chr(13, 10)
'  print sValue chr(13, 10)
'  print sDecimal chr(13, 10) 
'  print p[1] chr(13, 10)
'  print ci  chr(13, 10)

  byte b at strptr(f)

  int ci = len(sValue) 
  byte n at strptr(sValue) 'first the integer part.

  cm = -1
   
  for i = iBegin-1 to 1 step -1
    select case b[i]
        case 0 ' discard it!

        case 1, 2 ' 0 #
            p[1] -= 1         
            if p[1] <= 0 then
                if ci then
                    for ci = ci to 1 step -1
                       gosub addcomma
                       o = chr(n[ci]) + o                   
                    next ci
                elseif iFill then
                    if b[i] = 2 then
                        o = chr(iFill) + o
                    end if
                end if
            elseif p[1] > 0 then
                if ci then
                    gosub addcomma               
                    o = chr(n[ci]) + o
                    ci -= 1
                elseif b[i] = 1 then
                   gosub addcomma
                   o = "0" + o
                   
                elseif iFill then
                   o = chr(iFill) + o         
                end if               
            end if                   
       
        case else
            o = chr(b[i]) + o

    end select
  next i
 
  ' phew!! last... the decimals!
 
  int ci = 1   
  byte n at strptr(sDecimal)
 
  for i = iBegin to ml
    select case b[i]
        case 0 ' discard it!
        case 1, 2 ' 0 #
            p[2] -= 1         
            if p[2] < 0 then
                if iFill then
                    if b[i] = 2 then
                        o += chr(iFill)
                    end if           
                end if
            elseif p[2] = 0 then
                if ci = len(sDecimal) then
                    for ci = ci to len(sDecimal)
                       o += chr(n[ci])                   
                    next ci
                    if iPercent then
                        o += "%"
                    end if
                   
                elseif ci > len(sDecimal) then
                    if b[i] = 1 then
                        o += "0"
                    elseif iFill then
                        o += chr(iFill)
                    end if
                    if iPercent then
                        o += "%"
                    end if                   
                elseif iFill then
                    if b[i] = 2 then
                        o += chr(iFill)
                    end if
                end if
            elseif p[2] > 0 then
                if ci < len(sDecimal) then               
                    o += chr(n[ci])
                    ci += 1
                elseif b[i] = 1 then
                   o += "0"
                   
                elseif iFill then
                   o = chr(iFill) + o         
                end if               
            end if                   
       
        case else
            o += chr(b[i])

     end select
  next i 
 
  return o
 
addcomma:
  if iCommas then
     cm += 1
     if cm = 3 then
        cm = 0
        o = "," + o
     end if
  end if
ret

END FUNCTION

FUNCTION ¤FORMAT(double dd, string fs) AS STRING
    string f = fs
    return ¤FORMATCODE(dd, f, 8)
END FUNCTION

FUNCTION ¤FORMAT(single dd) AS STRING
    string f = ""
    return ¤FORMATCODE(dd, f, 8)
END FUNCTION

FUNCTION ¤FORMAT(quad dd) AS STRING
    string f = ""
    return ¤FORMATCODE(dd, f, 0)
END FUNCTION










' END OF FORMAT$.BIN
' STARTS ASCIIZ.BIN
//Assigns a truncated null terminated string.
MACRO ¤ASCZ_SET(v, c, l)
    if l < 2 then
        copy0(@v, chr(0), 1)
    else       
        copy0(@v, left(c, l-1), l)
    end if       
END MACRO
' END OF ASCIIZ.BIN
' STARTS CALLBACKDATA.BIN
' END OF CALLBACKDATA.BIN


DECLARE FUNCTION PBMAIN() AS INT


' Initializes various things in the script.
FUNCTION PluriBASIC_Initialize() AS LONG
END FUNCTION

FUNCTION PBMAIN() AS INT
   INT ¤RETVAL = 0
   ¤SYSERR Err
   INT in1
   STRING sbn2
   STRING sun3
   STRING san4
   SINGLE t1n5
   SINGLE t2n6
   INT c1n7
   INT c2n8
   INT in9
   WSTRING sbna
   WSTRING sunb
   WSTRING sanc
   SINGLE t1nd
   SINGLE t2ne
   INT c1nf
   INT c2n10
   INT in11
   STRING sbn12
   STRING sun13
   WSTRING san14
   SINGLE t1n15
   SINGLE t2n16
   INT c1n17
   INT c2n18
   INT in19
   STRING sbn1a
   STRING sun1b
   ASCIIZ san1c[22]
   SINGLE t1n1d
   SINGLE t2n1e
   INT c1n1f
   INT c2n20
   INT in21
   STRING sbn22
   STRING sun23
   WCHAR san24[22]
   SINGLE t1n25
   SINGLE t2n26
   INT c1n27
   INT c2n28
   INT in29
   CHAR sbn2a[22]
   CHAR sun2b[22]
   WSTRING san2c
   SINGLE t1n2d
   SINGLE t2n2e
   INT c1n2f
   INT c2n30
   INT in31
   CHAR sbn32[22]
   CHAR sun33[22]
   ASCIIZ san34[22]
   SINGLE t1n35
   SINGLE t2n36
   INT c1n37
   INT c2n38
   INT in39
   CHAR sbn3a[22]
   CHAR sun3b[22]
   CHAR san3c[22]
   SINGLE t1n3d
   SINGLE t2n3e
   INT c1n3f
   INT c2n40
   INT in41
   WCHAR sbn42[22]
   WCHAR sun43[22]
   WCHAR san44[22]
   SINGLE t1n45
   SINGLE t2n46
   INT c1n47
   INT c2n48
   INT in49
   WCHAR sbn4a[22]
   WCHAR sun4b[22]
   ASCIIZ san4c[22]
   SINGLE t1n4d
   SINGLE t2n4e
   INT c1n4f
   INT c2n50
   INT in51
   ASCIIZ sbn52[22]
   ASCIIZ sun53[22]
   ASCIIZ san54[22]
   SINGLE t1n55
   SINGLE t2n56
   INT c1n57
   INT c2n58
   ¤PRINTSTR("OxygenBASIC" & " benchmark for string comparison! (" & ¤STR(32, byval 0) & "bits)", 1)
   ¤PRINTSTR("", 1)
   sbn2 = ("concat")
   sun3 = ("compare1")
   san4 = ("compare2")
   t1n5 = (TIMER())
   FOR in1 = 1 TO 1000000
      IF (¤STREQL(sbn2 + sun3, sbn2 + sun3)) THEN
         c1n7 = ((c1n7) + 1)
      END IF
      IF ¤STRDIF(sbn2 + sun3, sbn2 + san4) THEN
         c2n8 = ((c2n8) + 1)
      END IF
   NEXT
   t2n6 = (TIMER())
   ¤PRINTSTR(IIF(((c1n7=1000000)) AND ((c2n8=1000000)), "*OK!* ", "ERROR ") & ¤FORMAT(t2n6 - t1n5, "0.000") & "  " & "STRING" & IIF(0, " *" & ¤STR(0, byval 0), "") & " vs " & "STRING" & IIF(0, " *" & ¤STR(0, byval 0), "") & "  ", 1)
   sbna = ("concat")
   sunb = ("compare1")
   sanc = ("compare2")
   t1nd = (TIMER())
   FOR in9 = 1 TO 1000000
      IF (¤STREQL(sbna + sunb, sbna + sunb)) THEN
         c1nf = ((c1nf) + 1)
      END IF
      IF ¤STRDIF(sbna + sunb, sbna + sanc) THEN
         c2n10 = ((c2n10) + 1)
      END IF
   NEXT
   t2ne = (TIMER())
   ¤PRINTSTR(IIF(((c1nf=1000000)) AND ((c2n10=1000000)), "*OK!* ", "ERROR ") & ¤FORMAT(t2ne - t1nd, "0.000") & "  " & "WSTRING" & IIF(0, " *" & ¤STR(0, byval 0), "") & " vs " & "WSTRING" & IIF(0, " *" & ¤STR(0, byval 0), "") & "  ", 1)
   sbn12 = ("concat")
   sun13 = ("compare1")
   san14 = ("compare2")
   t1n15 = (TIMER())
   FOR in11 = 1 TO 1000000
      IF (¤STREQL(sbn12 + sun13, sbn12 + sun13)) THEN
         c1n17 = ((c1n17) + 1)
      END IF
      IF ¤STRDIF(sbn12 + sun13, sbn12 + san14) THEN
         c2n18 = ((c2n18) + 1)
      END IF
   NEXT
   t2n16 = (TIMER())
   ¤PRINTSTR(IIF(((c1n17=1000000)) AND ((c2n18=1000000)), "*OK!* ", "ERROR ") & ¤FORMAT(t2n16 - t1n15, "0.000") & "  " & "STRING" & IIF(0, " *" & ¤STR(0, byval 0), "") & " vs " & "WSTRING" & IIF(0, " *" & ¤STR(0, byval 0), "") & "  ", 1)
   sbn1a = ("concat")
   sun1b = ("compare1")
   ¤ASCZ_SET(san1c, ("compare2"), 20)
   t1n1d = (TIMER())
   FOR in19 = 1 TO 1000000
      IF (¤STREQL(sbn1a + sun1b, sbn1a + sun1b)) THEN
         c1n1f = ((c1n1f) + 1)
      END IF
      IF ¤STRDIF(sbn1a + sun1b, sbn1a + san1c) THEN
         c2n20 = ((c2n20) + 1)
      END IF
   NEXT
   t2n1e = (TIMER())
   ¤PRINTSTR(IIF(((c1n1f=1000000)) AND ((c2n20=1000000)), "*OK!* ", "ERROR ") & ¤FORMAT(t2n1e - t1n1d, "0.000") & "  " & "STRING" & IIF(0, " *" & ¤STR(0, byval 0), "") & " vs " & "ASCIIZ" & IIF(20, " *" & ¤STR(20, byval 0), "") & "  ", 1)
   sbn22 = ("concat")
   sun23 = ("compare1")
   ¤WSTR_SET(san24, ("compare2"), 20)
   t1n25 = (TIMER())
   FOR in21 = 1 TO 1000000
      IF (¤STREQL(sbn22 + sun23, sbn22 + sun23)) THEN
         c1n27 = ((c1n27) + 1)
      END IF
      IF ¤STRDIF(sbn22 + sun23, sbn22 + san24) THEN
         c2n28 = ((c2n28) + 1)
      END IF
   NEXT
   t2n26 = (TIMER())
   ¤PRINTSTR(IIF(((c1n27=1000000)) AND ((c2n28=1000000)), "*OK!* ", "ERROR ") & ¤FORMAT(t2n26 - t1n25, "0.000") & "  " & "STRING" & IIF(0, " *" & ¤STR(0, byval 0), "") & " vs " & "WSTRING" & IIF(20, " *" & ¤STR(20, byval 0), "") & "  ", 1)
   ¤STRN_SET(sbn2a, ("concat"), 20)
   ¤STRN_SET(sun2b, ("compare1"), 20)
   san2c = ("compare2")
   t1n2d = (TIMER())
   FOR in29 = 1 TO 1000000
      IF (¤STREQL(sbn2a + sun2b, sbn2a + sun2b)) THEN
         c1n2f = ((c1n2f) + 1)
      END IF
      IF ¤STRDIF(sbn2a + sun2b, sbn2a + san2c) THEN
         c2n30 = ((c2n30) + 1)
      END IF
   NEXT
   t2n2e = (TIMER())
   ¤PRINTSTR(IIF(((c1n2f=1000000)) AND ((c2n30=1000000)), "*OK!* ", "ERROR ") & ¤FORMAT(t2n2e - t1n2d, "0.000") & "  " & "STRING" & IIF(20, " *" & ¤STR(20, byval 0), "") & " vs " & "WSTRING" & IIF(0, " *" & ¤STR(0, byval 0), "") & "  ", 1)
   ¤STRN_SET(sbn32, ("concat"), 20)
   ¤STRN_SET(sun33, ("compare1"), 20)
   ¤ASCZ_SET(san34, ("compare2"), 20)
   t1n35 = (TIMER())
   FOR in31 = 1 TO 1000000
      IF (¤STREQL(sbn32 + sun33, sbn32 + sun33)) THEN
         c1n37 = ((c1n37) + 1)
      END IF
      IF ¤STRDIF(sbn32 + sun33, sbn32 + san34) THEN
         c2n38 = ((c2n38) + 1)
      END IF
   NEXT
   t2n36 = (TIMER())
   ¤PRINTSTR(IIF(((c1n37=1000000)) AND ((c2n38=1000000)), "*OK!* ", "ERROR ") & ¤FORMAT(t2n36 - t1n35, "0.000") & "  " & "STRING" & IIF(20, " *" & ¤STR(20, byval 0), "") & " vs " & "ASCIIZ" & IIF(20, " *" & ¤STR(20, byval 0), "") & "  ", 1)
   ¤STRN_SET(sbn3a, ("concat"), 20)
   ¤STRN_SET(sun3b, ("compare1"), 20)
   ¤STRN_SET(san3c, ("compare2"), 20)
   t1n3d = (TIMER())
   FOR in39 = 1 TO 1000000
      IF (¤STREQL(sbn3a + sun3b, sbn3a + sun3b)) THEN
         c1n3f = ((c1n3f) + 1)
      END IF
      IF ¤STRDIF(sbn3a + sun3b, sbn3a + san3c) THEN
         c2n40 = ((c2n40) + 1)
      END IF
   NEXT
   t2n3e = (TIMER())
   ¤PRINTSTR(IIF(((c1n3f=1000000)) AND ((c2n40=1000000)), "*OK!* ", "ERROR ") & ¤FORMAT(t2n3e - t1n3d, "0.000") & "  " & "STRING" & IIF(20, " *" & ¤STR(20, byval 0), "") & " vs " & "STRING" & IIF(20, " *" & ¤STR(20, byval 0), "") & "  ", 1)
   ¤WSTR_SET(sbn42, ("concat"), 20)
   ¤WSTR_SET(sun43, ("compare1"), 20)
   ¤WSTR_SET(san44, ("compare2"), 20)
   t1n45 = (TIMER())
   FOR in41 = 1 TO 1000000
      IF (¤STREQL(sbn42 + sun43, sbn42 + sun43)) THEN
         c1n47 = ((c1n47) + 1)
      END IF
      IF ¤STRDIF(sbn42 + sun43, sbn42 + san44) THEN
         c2n48 = ((c2n48) + 1)
      END IF
   NEXT
   t2n46 = (TIMER())
   ¤PRINTSTR(IIF(((c1n47=1000000)) AND ((c2n48=1000000)), "*OK!* ", "ERROR ") & ¤FORMAT(t2n46 - t1n45, "0.000") & "  " & "WSTRING" & IIF(20, " *" & ¤STR(20, byval 0), "") & " vs " & "WSTRING" & IIF(20, " *" & ¤STR(20, byval 0), "") & "  ", 1)
   ¤WSTR_SET(sbn4a, ("concat"), 20)
   ¤WSTR_SET(sun4b, ("compare1"), 20)
   ¤ASCZ_SET(san4c, ("compare2"), 20)
   t1n4d = (TIMER())
   FOR in49 = 1 TO 1000000
      IF (¤STREQL(sbn4a + sun4b, sbn4a + sun4b)) THEN
         c1n4f = ((c1n4f) + 1)
      END IF
      IF ¤STRDIF(sbn4a + sun4b, sbn4a + san4c) THEN
         c2n50 = ((c2n50) + 1)
      END IF
   NEXT
   t2n4e = (TIMER())
   ¤PRINTSTR(IIF(((c1n4f=1000000)) AND ((c2n50=1000000)), "*OK!* ", "ERROR ") & ¤FORMAT(t2n4e - t1n4d, "0.000") & "  " & "WSTRING" & IIF(20, " *" & ¤STR(20, byval 0), "") & " vs " & "ASCIIZ" & IIF(20, " *" & ¤STR(20, byval 0), "") & "  ", 1)
   ¤ASCZ_SET(sbn52, ("concat"), 20)
   ¤ASCZ_SET(sun53, ("compare1"), 20)
   ¤ASCZ_SET(san54, ("compare2"), 20)
   t1n55 = (TIMER())
   FOR in51 = 1 TO 1000000
      IF (¤STREQL(sbn52 + sun53, sbn52 + sun53)) THEN
         c1n57 = ((c1n57) + 1)
      END IF
      IF ¤STRDIF(sbn52 + sun53, sbn52 + san54) THEN
         c2n58 = ((c2n58) + 1)
      END IF
   NEXT
   t2n56 = (TIMER())
   ¤PRINTSTR(IIF(((c1n57=1000000)) AND ((c2n58=1000000)), "*OK!* ", "ERROR ") & ¤FORMAT(t2n56 - t1n55, "0.000") & "  " & "ASCIIZ" & IIF(20, " *" & ¤STR(20, byval 0), "") & " vs " & "ASCIIZ" & IIF(20, " *" & ¤STR(20, byval 0), "") & "  ", 1)
   RETURN ¤RETVAL
END FUNCTION

PBMAIN() ' invoke entry point

Code: [Select]
'Generated with PluriBASIC 6.0.237326.0

#COMPILE EXE
#DIM ALL


GLOBAL SYSTEM_UDT_OFFSETS() AS STRING
DECLARE FUNCTION WriteFile_2        LIB "KERNEL32.DLL" ALIAS "WriteFile" (BYVAL hFile AS DWORD, lpBuffer AS ANY, BYVAL nNumberOfBytesToWrite AS LONG, lpNumberOfBytesWritten AS LONG, lpOverlapped AS ANY) AS LONG
DECLARE FUNCTION WriteConsole_2     LIB "KERNEL32.DLL" ALIAS "WriteFile" (BYVAL hFile AS DWORD, lpBuffer AS ANY, BYVAL nNumberOfBytesToWrite AS LONG, lpNumberOfBytesWritten AS LONG, lpOverlapped AS ANY) AS LONG
DECLARE FUNCTION AllocConsole_2     LIB "KERNEL32.DLL" ALIAS "AllocConsole" () AS LONG
DECLARE FUNCTION FlushFileBuffers_2 LIB "KERNEL32.DLL" ALIAS "FlushFileBuffers" (BYVAL hFile AS DWORD) AS LONG
DECLARE FUNCTION GetStdHandle_2     LIB "KERNEL32.DLL" Alias "GetStdHandle" (ByVal nStdHandle AS DWORD) AS DWORD


DECLARE FUNCTION PBMAIN() AS LONG
GLOBAL default_form  AS STRING

' STARTS PLURIBASIC_PREPARE.BIN

FUNCTION OPE_SHIFTLEFT(BYVAL V1 AS QUAD, BYVAL V2 AS QUAD) AS QUAD
    SHIFT LEFT V1, V2
    FUNCTION = V1
END FUNCTION

FUNCTION OPE_SHIFTRIGHT(BYVAL V1 AS QUAD, BYVAL V2 AS QUAD) AS QUAD
    SHIFT RIGHT V1, V2
    FUNCTION = V1
END FUNCTION

' END OF PLURIBASIC_PREPARE.BIN
' STARTS PRINTR.BIN

   
SUB PRINTR(byval s AS STRING, byval cr as long)               
             
  STATIC Allc    AS LONG
  LOCAL lWritten AS LONG     
  LOCAL hFile    AS DWORD
  LOCAL Btc      AS LONG
  LOCAL TTsnd    AS STRING

  IF isfalse(Allc) THEN
    CALL AllocConsole_2()
    Allc = 1
  END IF

  if cr=1 then S += $CRLF
  if cr=2 then S += "</br>"
 
  SLEEP 0
  hFile = GetStdHandle_2(-11)
  For Btc = 1 to 50     
     if ((Btc*32000)-31999) > len(s) THEN exit for
     TTsnd = MID$(s, ((Btc*32000)-31999), 32000)
     WriteConsole_2(hFile, ByVal StrPtr(TTsnd), Len(TTsnd), lWritten, ByVal 0&)
  Next Btc
 
  'FlushFileBuffers_2(hFile)
     
END SUB
' END OF PRINTR.BIN
' STARTS PLURIBASIC_INIT.BIN
'
FUNCTION PLURIBASIC_INIT( ) AS LONG

END FUNCTION

' END OF PLURIBASIC_INIT.BIN

' Initializes various things in the script.
FUNCTION PluriBASIC_Initialize() AS LONG
   DIM SYSTEM_UDT_OFFSETS(0) AS GLOBAL STRING
END FUNCTION

FUNCTION PBMAIN() AS LONG
   LOCAL in1 AS LONG
   LOCAL sbn2 AS STRING
   LOCAL sun3 AS STRING
   LOCAL san4 AS STRING
   LOCAL t1n5 AS SINGLE
   LOCAL t2n6 AS SINGLE
   LOCAL c1n7 AS LONG
   LOCAL c2n8 AS LONG
   LOCAL in9 AS LONG
   LOCAL sbna AS WSTRING
   LOCAL sunb AS WSTRING
   LOCAL sanc AS WSTRING
   LOCAL t1nd AS SINGLE
   LOCAL t2ne AS SINGLE
   LOCAL c1nf AS LONG
   LOCAL c2n10 AS LONG
   LOCAL in11 AS LONG
   LOCAL sbn12 AS STRING
   LOCAL sun13 AS STRING
   LOCAL san14 AS WSTRING
   LOCAL t1n15 AS SINGLE
   LOCAL t2n16 AS SINGLE
   LOCAL c1n17 AS LONG
   LOCAL c2n18 AS LONG
   LOCAL in19 AS LONG
   LOCAL sbn1a AS STRING
   LOCAL sun1b AS STRING
   LOCAL san1c AS ASCIIZ * 20
   LOCAL t1n1d AS SINGLE
   LOCAL t2n1e AS SINGLE
   LOCAL c1n1f AS LONG
   LOCAL c2n20 AS LONG
   LOCAL in21 AS LONG
   LOCAL sbn22 AS STRING
   LOCAL sun23 AS STRING
   LOCAL san24 AS WSTRING * 20
   LOCAL t1n25 AS SINGLE
   LOCAL t2n26 AS SINGLE
   LOCAL c1n27 AS LONG
   LOCAL c2n28 AS LONG
   LOCAL in29 AS LONG
   LOCAL sbn2a AS STRING * 20
   LOCAL sun2b AS STRING * 20
   LOCAL san2c AS WSTRING
   LOCAL t1n2d AS SINGLE
   LOCAL t2n2e AS SINGLE
   LOCAL c1n2f AS LONG
   LOCAL c2n30 AS LONG
   LOCAL in31 AS LONG
   LOCAL sbn32 AS STRING * 20
   LOCAL sun33 AS STRING * 20
   LOCAL san34 AS ASCIIZ * 20
   LOCAL t1n35 AS SINGLE
   LOCAL t2n36 AS SINGLE
   LOCAL c1n37 AS LONG
   LOCAL c2n38 AS LONG
   LOCAL in39 AS LONG
   LOCAL sbn3a AS STRING * 20
   LOCAL sun3b AS STRING * 20
   LOCAL san3c AS STRING * 20
   LOCAL t1n3d AS SINGLE
   LOCAL t2n3e AS SINGLE
   LOCAL c1n3f AS LONG
   LOCAL c2n40 AS LONG
   LOCAL in41 AS LONG
   LOCAL sbn42 AS WSTRING * 20
   LOCAL sun43 AS WSTRING * 20
   LOCAL san44 AS WSTRING * 20
   LOCAL t1n45 AS SINGLE
   LOCAL t2n46 AS SINGLE
   LOCAL c1n47 AS LONG
   LOCAL c2n48 AS LONG
   LOCAL in49 AS LONG
   LOCAL sbn4a AS WSTRING * 20
   LOCAL sun4b AS WSTRING * 20
   LOCAL san4c AS ASCIIZ * 20
   LOCAL t1n4d AS SINGLE
   LOCAL t2n4e AS SINGLE
   LOCAL c1n4f AS LONG
   LOCAL c2n50 AS LONG
   LOCAL in51 AS LONG
   LOCAL sbn52 AS ASCIIZ * 20
   LOCAL sun53 AS ASCIIZ * 20
   LOCAL san54 AS ASCIIZ * 20
   LOCAL t1n55 AS SINGLE
   LOCAL t2n56 AS SINGLE
   LOCAL c1n57 AS LONG
   LOCAL c2n58 AS LONG
   PRINTR("PowerBASIC for Windows" & " benchmark for string comparison! (" & STR$(32) & "bits)", 1)
   PRINTR("", 1)
   sbn2 = "concat"
   sun3 = "compare1"
   san4 = "compare2"
   t1n5 = TIMER
   FOR in1 = 1 TO 1000000
      IF (sbn2 + sun3=sbn2 + sun3) THEN
         c1n7 = ((c1n7) + 1)
      END IF
      IF sbn2 + sun3 <> sbn2 + san4 THEN
         c2n8 = ((c2n8) + 1)
      END IF
   NEXT
   t2n6 = TIMER
   PRINTR(IIF$(((c1n7=1000000)) AND ((c2n8=1000000)), "*OK!* ", "ERROR ") &  _
       FORMAT$(t2n6 - t1n5, "0.000") & "  " &  _
       "STRING" &  _
       IIF$(0, " *" & STR$(0), "") &  _
       " vs " & "STRING" &  _
       IIF$(0, " *" & STR$(0), "") &  _
       "  ", 1)
   sbna = "concat"
   sunb = "compare1"
   sanc = "compare2"
   t1nd = TIMER
   FOR in9 = 1 TO 1000000
      IF (sbna + sunb=sbna + sunb) THEN
         c1nf = ((c1nf) + 1)
      END IF
      IF sbna + sunb <> sbna + sanc THEN
         c2n10 = ((c2n10) + 1)
      END IF
   NEXT
   t2ne = TIMER
   PRINTR(IIF$(((c1nf=1000000)) AND ((c2n10=1000000)), "*OK!* ", "ERROR ") &  _
       FORMAT$(t2ne - t1nd, "0.000") & "  " &  _
       "WSTRING" &  _
       IIF$(0, " *" & STR$(0), "") &  _
       " vs " & "WSTRING" &  _
       IIF$(0, " *" & STR$(0), "") &  _
       "  ", 1)
   sbn12 = "concat"
   sun13 = "compare1"
   san14 = "compare2"
   t1n15 = TIMER
   FOR in11 = 1 TO 1000000
      IF (sbn12 + sun13=sbn12 + sun13) THEN
         c1n17 = ((c1n17) + 1)
      END IF
      IF sbn12 + sun13 <> sbn12 + san14 THEN
         c2n18 = ((c2n18) + 1)
      END IF
   NEXT
   t2n16 = TIMER
   PRINTR(IIF$(((c1n17=1000000)) AND ((c2n18=1000000)), "*OK!* ", "ERROR ") &  _
       FORMAT$(t2n16 - t1n15, "0.000") & "  " &  _
       "STRING" &  _
       IIF$(0, " *" & STR$(0), "") &  _
       " vs " & "WSTRING" &  _
       IIF$(0, " *" & STR$(0), "") &  _
       "  ", 1)
   sbn1a = "concat"
   sun1b = "compare1"
   san1c = "compare2"
   t1n1d = TIMER
   FOR in19 = 1 TO 1000000
      IF (sbn1a + sun1b=sbn1a + sun1b) THEN
         c1n1f = ((c1n1f) + 1)
      END IF
      IF sbn1a + sun1b <> sbn1a + san1c THEN
         c2n20 = ((c2n20) + 1)
      END IF
   NEXT
   t2n1e = TIMER
   PRINTR(IIF$(((c1n1f=1000000)) AND ((c2n20=1000000)), "*OK!* ", "ERROR ") &  _
       FORMAT$(t2n1e - t1n1d, "0.000") & "  " &  _
       "STRING" &  _
       IIF$(0, " *" & STR$(0), "") &  _
       " vs " & "ASCIIZ" &  _
       IIF$(20, " *" & STR$(20), "") &  _
       "  ", 1)
   sbn22 = "concat"
   sun23 = "compare1"
   san24 = "compare2"
   t1n25 = TIMER
   FOR in21 = 1 TO 1000000
      IF (sbn22 + sun23=sbn22 + sun23) THEN
         c1n27 = ((c1n27) + 1)
      END IF
      IF sbn22 + sun23 <> sbn22 + san24 THEN
         c2n28 = ((c2n28) + 1)
      END IF
   NEXT
   t2n26 = TIMER
   PRINTR(IIF$(((c1n27=1000000)) AND ((c2n28=1000000)), "*OK!* ", "ERROR ") &  _
       FORMAT$(t2n26 - t1n25, "0.000") & "  " &  _
       "STRING" &  _
       IIF$(0, " *" & STR$(0), "") &  _
       " vs " & "WSTRING" &  _
       IIF$(20, " *" & STR$(20), "") &  _
       "  ", 1)
   sbn2a = "concat"
   sun2b = "compare1"
   san2c = "compare2"
   t1n2d = TIMER
   FOR in29 = 1 TO 1000000
      IF (sbn2a + sun2b=sbn2a + sun2b) THEN
         c1n2f = ((c1n2f) + 1)
      END IF
      IF sbn2a + sun2b <> sbn2a + san2c THEN
         c2n30 = ((c2n30) + 1)
      END IF
   NEXT
   t2n2e = TIMER
   PRINTR(IIF$(((c1n2f=1000000)) AND ((c2n30=1000000)), "*OK!* ", "ERROR ") &  _
       FORMAT$(t2n2e - t1n2d, "0.000") & "  " &  _
       "STRING" &  _
       IIF$(20, " *" & STR$(20), "") &  _
       " vs " & "WSTRING" &  _
       IIF$(0, " *" & STR$(0), "") &  _
       "  ", 1)
   sbn32 = "concat"
   sun33 = "compare1"
   san34 = "compare2"
   t1n35 = TIMER
   FOR in31 = 1 TO 1000000
      IF (sbn32 + sun33=sbn32 + sun33) THEN
         c1n37 = ((c1n37) + 1)
      END IF
      IF sbn32 + sun33 <> sbn32 + san34 THEN
         c2n38 = ((c2n38) + 1)
      END IF
   NEXT
   t2n36 = TIMER
   PRINTR(IIF$(((c1n37=1000000)) AND ((c2n38=1000000)), "*OK!* ", "ERROR ") &  _
       FORMAT$(t2n36 - t1n35, "0.000") & "  " &  _
       "STRING" &  _
       IIF$(20, " *" & STR$(20), "") &  _
       " vs " & "ASCIIZ" &  _
       IIF$(20, " *" & STR$(20), "") &  _
       "  ", 1)
   sbn3a = "concat"
   sun3b = "compare1"
   san3c = "compare2"
   t1n3d = TIMER
   FOR in39 = 1 TO 1000000
      IF (sbn3a + sun3b=sbn3a + sun3b) THEN
         c1n3f = ((c1n3f) + 1)
      END IF
      IF sbn3a + sun3b <> sbn3a + san3c THEN
         c2n40 = ((c2n40) + 1)
      END IF
   NEXT
   t2n3e = TIMER
   PRINTR(IIF$(((c1n3f=1000000)) AND ((c2n40=1000000)), "*OK!* ", "ERROR ") &  _
       FORMAT$(t2n3e - t1n3d, "0.000") & "  " &  _
       "STRING" &  _
       IIF$(20, " *" & STR$(20), "") &  _
       " vs " & "STRING" &  _
       IIF$(20, " *" & STR$(20), "") &  _
       "  ", 1)
   sbn42 = "concat"
   sun43 = "compare1"
   san44 = "compare2"
   t1n45 = TIMER
   FOR in41 = 1 TO 1000000
      IF (sbn42 + sun43=sbn42 + sun43) THEN
         c1n47 = ((c1n47) + 1)
      END IF
      IF sbn42 + sun43 <> sbn42 + san44 THEN
         c2n48 = ((c2n48) + 1)
      END IF
   NEXT
   t2n46 = TIMER
   PRINTR(IIF$(((c1n47=1000000)) AND ((c2n48=1000000)), "*OK!* ", "ERROR ") &  _
       FORMAT$(t2n46 - t1n45, "0.000") & "  " &  _
       "WSTRING" &  _
       IIF$(20, " *" & STR$(20), "") &  _
       " vs " & "WSTRING" &  _
       IIF$(20, " *" & STR$(20), "") &  _
       "  ", 1)
   sbn4a = "concat"
   sun4b = "compare1"
   san4c = "compare2"
   t1n4d = TIMER
   FOR in49 = 1 TO 1000000
      IF (sbn4a + sun4b=sbn4a + sun4b) THEN
         c1n4f = ((c1n4f) + 1)
      END IF
      IF sbn4a + sun4b <> sbn4a + san4c THEN
         c2n50 = ((c2n50) + 1)
      END IF
   NEXT
   t2n4e = TIMER
   PRINTR(IIF$(((c1n4f=1000000)) AND ((c2n50=1000000)), "*OK!* ", "ERROR ") &  _
       FORMAT$(t2n4e - t1n4d, "0.000") & "  " &  _
       "WSTRING" &  _
       IIF$(20, " *" & STR$(20), "") &  _
       " vs " & "ASCIIZ" &  _
       IIF$(20, " *" & STR$(20), "") &  _
       "  ", 1)
   sbn52 = "concat"
   sun53 = "compare1"
   san54 = "compare2"
   t1n55 = TIMER
   FOR in51 = 1 TO 1000000
      IF (sbn52 + sun53=sbn52 + sun53) THEN
         c1n57 = ((c1n57) + 1)
      END IF
      IF sbn52 + sun53 <> sbn52 + san54 THEN
         c2n58 = ((c2n58) + 1)
      END IF
   NEXT
   t2n56 = TIMER
   PRINTR(IIF$(((c1n57=1000000)) AND ((c2n58=1000000)), "*OK!* ", "ERROR ") &  _
       FORMAT$(t2n56 - t1n55, "0.000") & "  " &  _
       "ASCIIZ" &  _
       IIF$(20, " *" & STR$(20), "") &  _
       " vs " & "ASCIIZ" &  _
       IIF$(20, " *" & STR$(20), "") &  _
       "  ", 1)
END FUNCTION

« Last Edit: June 06, 2019, 01:47:03 AM by Brian Alvarez »

Brian Alvarez

  • Guest
Re: Benchmark time!
« Reply #12 on: June 06, 2019, 01:58:27 AM »
  Yes, i have PBCC and PluriBASIC works fine with it. This one uses PBCC's native STDOUT statements, rather than PluriBASIC ones.
Here are the results for it:

Code: [Select]
PowerBASIC Console Compiler benchmark for string comparison! ( 32bits)

*OK!* 0.517  STRING vs STRING 
*OK!* 0.534  WSTRING vs WSTRING 
*OK!* 0.796  STRING vs WSTRING 
*OK!* 0.599  STRING vs ASCIIZ * 20 
*OK!* 0.894  STRING vs WSTRING * 20 
*OK!* 1.448  STRING * 20 vs WSTRING 
*OK!* 1.179  STRING * 20 vs ASCIIZ * 20 
*OK!* 1.133  STRING * 20 vs STRING * 20 
*OK!* 1.347  WSTRING * 20 vs WSTRING * 20 
*OK!* 1.492  WSTRING * 20 vs ASCIIZ * 20 
*OK!* 1.271  ASCIIZ * 20 vs ASCIIZ * 20 

Brian Alvarez

  • Guest
Re: Benchmark time!
« Reply #13 on: September 30, 2019, 10:52:49 AM »
Look at this gorgeous numbers...

Code: [Select]
OxygenBASIC benchmark for string comparison! (64bits)

*OK!* 0.203  STRING vs STRING 
*OK!* 0.235  WSTRING vs WSTRING 
*OK!* 0.219  STRING vs WSTRING 
*OK!* 0.218  STRING vs ASCIIZ * 20 
*OK!* 0.219  STRING vs WSTRING * 20 
*OK!* 0.313  STRING * 20 vs WSTRING 
*OK!* 0.328  STRING * 20 vs ASCIIZ * 20 
*OK!* 0.328  STRING * 20 vs STRING * 20 
*OK!* 0.375  WSTRING * 20 vs WSTRING * 20 
*OK!* 0.375  WSTRING * 20 vs ASCIIZ * 20 
*OK!* 0.235  ASCIIZ * 20 vs ASCIIZ * 20 

And this beautiful lines-per-minute count... 8,465,136 lines per minute! :D

Code: [Select]
Successfully created: C:\Users\Diamante\Documents\PluriBASIC\Examples\ex_listview.exe

PluriBASIC 6.0.6.293216 for Windows, Copyright © 2010-2019 PluriBASIC® Inc.
PowerBASIC for Windows, Copyright (c) 1996-2019 PowerBasic Inc.

    Primary source: C:\Users\Diamante\Documents\PluriBASIC\Examples\ex_listview.bas {196109 total lines}
 Target conversion: ex_listview.exe (32 bits)
   Conversion time: 1.3900 seconds, at 8,465,136 lines/minute.
  Compilation time: 0.0880 seconds, at 229,772 lines/minute.
    Generated code: 4.88 kb
  Embedded objects: 47 bytes
      Support code: 322 bytes
        Other code: 6.03 kb
------------------------------------
       Source size: 11.27 kb
     Compiled size: 55.50 kb

Component Files:
----------------
C:\Users\Diamante\Documents\PluriBASIC\Examples\ex_listview.bas
C:\PowerBASICWin10\WinAPI\Win32Api.inc
C:\PowerBASICWin10\WinAPI\SdkDdkVer.inc
C:\PowerBASICWin10\WinAPI\NTStatus.inc
C:\PowerBASICWin10\WinAPI\WinDef.inc
C:\PowerBASICWin10\WinAPI\WinNT.inc
C:\PowerBASICWin10\WinAPI\BaseTSD.inc
C:\PowerBASICWin10\WinAPI\WTypes.inc
C:\PowerBASICWin10\WinAPI\excpt.inc
C:\PowerBASICWin10\WinAPI\ktmtypes.inc
C:\PowerBASICWin10\WinAPI\WinGDI.inc
C:\PowerBASICWin10\WinAPI\WinUser.inc
C:\PowerBASICWin10\WinAPI\tvout.inc
C:\PowerBASICWin10\WinAPI\WinResrc.inc
C:\PowerBASICWin10\WinAPI\dlgs.inc
C:\PowerBASICWin10\WinAPI\winver.inc
C:\PowerBASICWin10\WinAPI\verrsrc.inc
C:\PowerBASICWin10\WinAPI\WinBase.inc
C:\PowerBASICWin10\WinAPI\WinError.inc
C:\PowerBASICWin10\WinAPI\WinReg.inc
C:\PowerBASICWin10\WinAPI\Reason.inc
C:\PowerBASICWin10\WinAPI\WinNLS.inc
C:\PowerBASICWin10\WinAPI\PrSht.inc
C:\PowerBASICWin10\WinAPI\CommDlg.inc
C:\PowerBASICWin10\WinAPI\CommCtrl.inc
C:\PowerBASICWin10\WinAPI\ShlObj.inc
C:\PowerBASICWin10\WinAPI\WinCon.inc
C:\PowerBASICWin10\WinAPI\Ole2.inc
C:\PowerBASICWin10\WinAPI\ObjBase.inc
C:\PowerBASICWin10\WinAPI\ObjIdl.inc
C:\PowerBASICWin10\WinAPI\OleAuto.inc
C:\PowerBASICWin10\WinAPI\oaidl.inc
C:\PowerBASICWin10\WinAPI\ShlGuid.inc
C:\PowerBASICWin10\WinAPI\IsGuids.inc
C:\PowerBASICWin10\WinAPI\KnownFolders.inc
C:\PowerBASICWin10\WinAPI\ShTypes.inc
C:\PowerBASICWin10\WinAPI\WinNetWk.inc
C:\PowerBASICWin10\WinAPI\wnnc.inc
C:\PowerBASICWin10\WinAPI\ShellApi.inc
C:\PowerBASICWin10\WinAPI\IpHlpApi.inc
C:\PowerBASICWin10\WinAPI\ipexport.inc
C:\PowerBASICWin10\WinAPI\in6addr.inc
C:\PowerBASICWin10\WinAPI\inaddr.inc
C:\PowerBASICWin10\WinAPI\tcpestats.inc
C:\PowerBASICWin10\WinAPI\WinDns.inc
C:\PowerBASICWin10\WinAPI\Ws2Def.inc
C:\PowerBASICWin10\WinAPI\ws2ipdef.inc
C:\PowerBASICWin10\WinAPI\WinSock2.inc
C:\PowerBASICWin10\WinAPI\qos.inc
C:\PowerBASICWin10\WinAPI\iprtrmib.inc
C:\PowerBASICWin10\WinAPI\mprapi.inc
C:\PowerBASICWin10\WinAPI\lmcons.inc
C:\PowerBASICWin10\WinAPI\WinCred.inc
C:\PowerBASICWin10\WinAPI\ras.inc
C:\PowerBASICWin10\WinAPI\wincrypt.inc
C:\PowerBASICWin10\WinAPI\bcrypt.inc
C:\PowerBASICWin10\WinAPI\ncrypt.inc
C:\PowerBASICWin10\WinAPI\ipifcons.inc
C:\PowerBASICWin10\WinAPI\ipmib.inc
C:\PowerBASICWin10\WinAPI\ifmib.inc
C:\PowerBASICWin10\WinAPI\ifdef.inc
C:\PowerBASICWin10\WinAPI\nldef.inc
C:\PowerBASICWin10\WinAPI\tcpmib.inc
C:\PowerBASICWin10\WinAPI\udpmib.inc
C:\PowerBASICWin10\WinAPI\iptypes.inc
C:\PowerBASICWin10\WinAPI\time.inc
C:\PowerBASICWin10\WinAPI\netioapi.inc
C:\PowerBASICWin10\WinAPI\ntddndis.inc
C:\PowerBASICWin10\WinAPI\DevPropDef.inc
C:\PowerBASICWin10\WinAPI\pciprop.inc
C:\PowerBASICWin10\WinAPI\WinDot11.inc
C:\PowerBASICWin10\WinAPI\WlanTypes.inc
C:\PowerBASICWin10\WinAPI\Mcx.inc
C:\PowerBASICWin10\WinAPI\MMSystem.inc
C:\PowerBASICWin10\WinAPI\UrlMon.inc
C:\PowerBASICWin10\WinAPI\WindowsX.inc

Generated Files:
----------------

JRS

  • Guest
Re: Benchmark time!
« Reply #14 on: September 30, 2019, 09:00:14 PM »
So much for handcrafted.

Does anyone know what PowerBasic sold for?