|
Post by jcfuller on Feb 6, 2016 23:50:39 GMT 1
Peter, Is this cheating Using my new UbxBasic and GStrings ? James $ONEXIT "~/UbxBasic/glib_build.sh $FILE$ -s" $GLIB Raw As GString Ptr gs gs = g_string_sized_new(20001) Dim i As Integer For i = 1 To 200000 gs = g_string_append_c(gs,ASC("@")) Next i Print Right$(gs$->str,10)
james@james-DX4870:~/UbxBasic/examples/jcf/strwork$ time ./t02 @@@@@@@@@@ real 0m0.003s user 0m0.000s sys 0m0.000s =============================================================== james@james-DX4870:~/UbxBasic/examples/jcf/strwork$ ls -ls total 44 12 -rwxrwxr-x 1 james james 10424 Feb 6 15:13 t01 4 -rw-rw-r-- 1 james james 148 Feb 6 15:13 t01.bas 8 -rw-rw-r-- 1 james james 5527 Feb 6 15:13 t01.c 8 -rwxrwxr-x 1 james james 6328 Feb 6 17:39 t02 4 -rw-rw-r-- 1 james james 212 Feb 6 17:39 t02.bas 8 -rw-rw-r-- 1 james james 5147 Feb 6 17:39 t02.c
|
|
|
Post by Pjot on Feb 7, 2016 8:13:02 GMT 1
Hi James, If there is a new version of UbxBasic then I am happy to test it as well! But using an external lib is cheating, of course In that case, I can use SDS myself to achieve a good ranking. Within the world of Basic it seems that BaCon (and also BCX) have a good ranking when it comes to string processing. Maybe 1 or 2 BASIC implementations are faster (e.g. FreeBasic, maybe Gambas which I still need to check out). But what bothers me with this test is that interpreters like Python and Awk achieve a better string processing performance I guess we need to study their source to see how they implement it. BR Peter
|
|
|
Post by Pjot on Feb 7, 2016 16:57:07 GMT 1
All, As conclusion, a final chart comparing BASIC performances. Also I have checked the latest incarnation of James Fuller's UbxBasic (64 bit Version 1.0.3.9 - mentioned as BCX in the chart below). Its performance for this particular benchmark program is the same, however, the resulting binary created by UbxBasic is only 6312 bytes, which is a lot smaller than the one generated by BaCon (10600 bytes) BR Peter
|
|
|
Post by jcfuller on Feb 7, 2016 18:26:27 GMT 1
Peter, How about giving the new kid on the block one more try. UbxBasic also translates to c++. See how this performs on your system. James
$CPPHDR $ONEXIT "~/UbxBasic/glib_build_cpp.sh $FILE$" Raw As stdstr BLA Dim As Integer i For i = 1 To 200000 BLA.append("@") Next i cout << "UbxBasic" << endl
|
|
|
Post by Pjot on Feb 7, 2016 19:14:34 GMT 1
Thanks James,
That's a lot better! But the functionality is not the same. I mean, appending one character to an existing string is not the same as creating a new string like 'a$ = a$ + b$'.
So therefore, this change would be valid (hope you agree):
$CPPHDR $ONEXIT "~/UbxBasic/glib_build_cpp.sh $FILE$" Raw As stdstr BLA Dim As Integer i For i = 1 To 200000 // BLA.append(Chr$(64)) BLA = BLA + Chr$(64) Next i cout << "UbxBasic" << endl
Now this code also runs blazingly fast. After multiple runs I can measure 1.265 seconds, which puts BCX on 2nd place (chart above updated).
BR Peter
|
|
|
Post by jcfuller on Feb 8, 2016 10:31:23 GMT 1
You are of course correct and I agree to the changes.
James
|
|
|
Post by jcfuller on Feb 8, 2016 10:41:29 GMT 1
Peter, I took a quick look at the FreeBasic source and see why it is so fast with it's native string. Try the FreeBasic test using a Zstring * 200001 for a comparison. With UbxBasic I primarily code for c++ and use stdstr (std::string).
James
|
|
|
Post by Pjot on Feb 8, 2016 21:01:28 GMT 1
Thx James, As with FreePascal, it seems that FreeBasic uses a specific binary layout for strings. This is similar to the approach of the Better String Library. The downside of this approach is that it is not compatible with existing libc functions like 'printf' or 'strcmp'. And neither with embedded C code within the BASIC program. So to achieve such compatibility, we could use the ideas from the SDS library or the GB String library instead. They allocate a few bytes before the actual string with some additional information about buffer length and string length. However, in case of string functions which use a variable amount of arguments (for example 'CONCAT$' or the '&' infix string concatenator), we do not know what comes in. For example, it could be that the BASIC program wants to concatenate hard coded strings, like "HELLO" and "WORLD". Obviously, these hard coded strings do not have these few bytes allocated in front of them, and checking for it would cause a segmentation fault. I could introduce a special type of strings with a particular binary layout (same as FreePascal / FreeBasic) and make the current string functions to become aware of them. Or create some special string functions for them. This would be last resort solution. Currently, I am looking into the idea of storing the memory address of a C string into a Key/Value table, to ensure storage and quick lookup of the buffer and string length. This would be my favorite, as it would be most generic, though the performance gain would be mostly visible for longer strings. So a lot to sort out, BR Peter
|
|
|
Post by alexfish on Feb 8, 2016 22:00:09 GMT 1
Hi Peter
these are some bench marks for the Raspberry PI 2 ,
BaCon 3.3 beta
GCC using SDS string
G++ using string
iterations = 50,000
BR Alex
|
|
|
Post by Pjot on Mar 4, 2016 18:31:54 GMT 1
All, After several attempts on improving the string performance, I now have a new beta ready. This was the infamous bench program: BLA$ = ""
FOR i = 1 TO 200000 BLA$ = BLA$ & "@" NEXT
PRINT "BaCon"
After compilation with the new beta, it now runs in 820 msecs. In the previous version it ran in 1901 msecs. So this is a performance gain of almost 57%, more than twice as fast. The performance is notably faster when using long strings. For example, when using the "Apply indentation" option for a large program in the GUI. For short and very short strings, the performance has gone down slightly (approx 10-40 msecs). In the upcoming weeks I will finetune the current setup further to overcome this. I hope the new beta works well, as there were some very heavy changes under the hood. Please let me know if you run into problems when trying it out. BR Peter
|
|
|
Post by vovchik on Mar 4, 2016 23:18:51 GMT 1
Dear Peter, Thanks very much. I tested with some 10 programs so far and everything is working. I haven't done any speed tests, but compilation is very quick, including progs with a lot of long strings. With kind regards, vovchik
|
|
|
Post by Pjot on Mar 5, 2016 12:49:01 GMT 1
Thanks vovchik, The implementation which optimizes string operations has been quite a nightmare. I have written down some notes about it. BR Peter
|
|
|
Post by vovchik on Mar 5, 2016 20:43:29 GMT 1
Dear Peter, I see it was a complex task, accompanied by much experimentation. So far, it is working very nicely and I have experienced no bugs, so thanks again and congratulations. With kind regards, vovchik
|
|
|
Post by Pjot on Mar 16, 2016 20:35:04 GMT 1
Thanks vovchik! The latest improvements indeed seem to be working well. In the meantime, I managed to increase the overall BaCon performance even more by using static character pointers in functions, to avoid unnecessary allocations and frees. I have updated the gory details on string optimization further. To compare the difference, when the benchmark program is compiled using the current stable release BaCon version 3.2.2 it runs in an average of 3312 milliseconds, while compiled with the latest beta it runs in 820 msecs average. This is a performance gain of 100-820/3312*100 = 75%. Below the latest overview with results from the benchmark program. With the new optimizations BaCon now ends second position. Hope this is good enough for everybody BR Peter
|
|
|
Post by alexfish on Mar 16, 2016 21:47:29 GMT 1
Hi Peter
latest bench for raspberry , rather impressive
here iterations = 50,000
BLA$ = ""
FOR i = 1 TO 50000 BLA$ = BLA$ & "@" NEXT
old bench mark
latest
BR Alex
|
|