News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Fast string builder - can I have some timings please?

Started by jj2007, October 16, 2020, 12:43:29 PM

Previous topic - Next topic

jj2007

I've always been deeply impressed by the "string builder classes" offered by really advanced languages like e.g. Java:

QuoteThe StringBuilder Class
StringBuilder objects are like String objects, except that they can be modified. Internally, these objects are treated like variable-length arrays that contain a sequence of characters. At any point, the length and content of the sequence can be changed through method invocations.

Strings should always be used unless string builders offer an advantage in terms of simpler code (see the sample program at the end of this section) or better performance. For example, if you need to concatenate a large number of strings, appending to a StringBuilder object is more efficient.

That goes on for about 5 pages and ends with some really simple examples. Something similar for C++ is discussed here at StackOverflow (it's only 10 pages to read, go ahead if you have masochistic tendencies).

However, I believe in simple, basic things, and in fast assembly code! So I wrote a StringBuild macro:

include \masm32\MasmBasic\MasmBasic.inc ; download
  Init
  PrintCpu 0
  For_ ecx=0 To 9
NanoTimer()
StringBuild edi ; ---------- start building the string
Let edi="You may initialise the string:"
For_ ecx=1 To 70000
Let edi=CrLf$+"string "+Str$("#%i", ecx)
Next
StringBuild ; ---------- stop string building
PrintLine NanoTimer$(), " for stringbuilder, 70000 strings with 1MB default allocation"
  Next
  PrintLine CrLf$, "The result: [", Left$(edi, 50), "...", Right$(edi, 50), Str$("], len=%i bytes", Len(edi)), CrLf$
  Inkey "Try the normal concat(y)?"
  .if eax=="y"
Clr$ edi
PrintLine CrLf$, "This may take a while..."
NanoTimer()
Let edi="You may initialise the string:"
For_ ecx=1 To 70000
Let edi=edi+CrLf$+"string "+Str$("#%i", ecx)
Next
PrintLine NanoTimer$(), " for normal concatenation, 70000 strings"
Inkey CrLf$, "The result: [", Left$(edi, 50), "...", Right$(edi, 50), Str$("], len=%i bytes", Len(edi)), CrLf$
  .endif
EndOfCode


Output:
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
15 ms for stringbuilder, 70000 strings with 1MB default allocation
15 ms for stringbuilder, 70000 strings with 1MB default allocation
15 ms for stringbuilder, 70000 strings with 1MB default allocation
15 ms for stringbuilder, 70000 strings with 1MB default allocation
15 ms for stringbuilder, 70000 strings with 1MB default allocation
15 ms for stringbuilder, 70000 strings with 1MB default allocation
15 ms for stringbuilder, 70000 strings with 1MB default allocation
15 ms for stringbuilder, 70000 strings with 1MB default allocation
15 ms for stringbuilder, 70000 strings with 1MB default allocation
15 ms for stringbuilder, 70000 strings with 1MB default allocation

The result: [You may initialise the string:
string #1
string ...69997
string #69998
string #69999
string #70000], len=1038924 bytes

Try the normal concat(y)?
This may take a while...
12 s for normal concatenation, 70000 strings

The result: [You may initialise the string:
string #1
string ...69997
string #69998
string #69999
string #70000], len=1038924 bytes


Source & exe attached. Building requires MasmBasic 16 October 2020

guga

MY timings...But, i donĀ“t get it. What is this used for ?

AMD Ryzen 5 2400G with Radeon Vega Graphics
20 ms for stringbuilder, 70000 strings with 1MB default allocation
21 ms for stringbuilder, 70000 strings with 1MB default allocation
16 ms for stringbuilder, 70000 strings with 1MB default allocation
19 ms for stringbuilder, 70000 strings with 1MB default allocation
19 ms for stringbuilder, 70000 strings with 1MB default allocation
19 ms for stringbuilder, 70000 strings with 1MB default allocation
25 ms for stringbuilder, 70000 strings with 1MB default allocation
25 ms for stringbuilder, 70000 strings with 1MB default allocation
25 ms for stringbuilder, 70000 strings with 1MB default allocation
21 ms for stringbuilder, 70000 strings with 1MB default allocation

The result: [You may initialise the string:
string #1
string ...69997
string #69998
string #69999
string #70000], len=1038924 bytes

Try the normal concat(y)?
This may take a while...
16 s for normal concatenation, 70000 strings

The result: [You may initialise the string:
string #1
string ...69997
string #69998
string #69999
string #70000], len=1038924 bytes
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

jj2007

Thanks, Guga. Roughly a factor 1,000 faster than normal concatenation :tongue:

guga

Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

Siekmanski

Intel(R) Core(TM) i7-4930K CPU @ 3.40GHz
12 ms for stringbuilder, 70000 strings with 1MB default allocation
12 ms for stringbuilder, 70000 strings with 1MB default allocation
12 ms for stringbuilder, 70000 strings with 1MB default allocation
12 ms for stringbuilder, 70000 strings with 1MB default allocation
18 ms for stringbuilder, 70000 strings with 1MB default allocation
12 ms for stringbuilder, 70000 strings with 1MB default allocation
12 ms for stringbuilder, 70000 strings with 1MB default allocation
12 ms for stringbuilder, 70000 strings with 1MB default allocation
12 ms for stringbuilder, 70000 strings with 1MB default allocation
12 ms for stringbuilder, 70000 strings with 1MB default allocation

The result: [You may initialise the string:
string #1
string ...69997
string #69998
string #69999
string #70000], len=1038924 bytes

Try the normal concat(y)?
This may take a while...
12 s for normal concatenation, 70000 strings

The result: [You may initialise the string:
string #1
string ...69997
string #69998
string #69999
string #70000], len=1038924 bytes
Creative coders use backward thinking techniques as a strategy.

mineiro

$ wine StringBuildDemo.exe
Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
13 ms for stringbuilder, 70000 strings with 1MB default allocation
13 ms for stringbuilder, 70000 strings with 1MB default allocation
13 ms for stringbuilder, 70000 strings with 1MB default allocation
13 ms for stringbuilder, 70000 strings with 1MB default allocation
13 ms for stringbuilder, 70000 strings with 1MB default allocation
13 ms for stringbuilder, 70000 strings with 1MB default allocation
14 ms for stringbuilder, 70000 strings with 1MB default allocation
17 ms for stringbuilder, 70000 strings with 1MB default allocation
14 ms for stringbuilder, 70000 strings with 1MB default allocation
16 ms for stringbuilder, 70000 strings with 1MB default allocation

The result: [You may initialise the string:
string #1
string ...69997
string #69998
string #69999
string #70000], len=1038924 bytes

Try the normal concat(y)?
This may take a while...
12 s for normal concatenation, 70000 strings

The result: [You may initialise the string:
string #1
string ...69997
string #69998
string #69999
string #70000], len=1038924 bytes
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

TouEnMasm


Intel(R) Core(TM) i3-4150 CPU @ 3.50GHz
15 ms for stringbuilder, 70000 strings with 1MB default allocation
16 ms for stringbuilder, 70000 strings with 1MB default allocation
19 ms for stringbuilder, 70000 strings with 1MB default allocation
12 ms for stringbuilder, 70000 strings with 1MB default allocation
12 ms for stringbuilder, 70000 strings with 1MB default allocation
12 ms for stringbuilder, 70000 strings with 1MB default allocation
18 ms for stringbuilder, 70000 strings with 1MB default allocation
12 ms for stringbuilder, 70000 strings with 1MB default allocation
18 ms for stringbuilder, 70000 strings with 1MB default allocation
19 ms for stringbuilder, 70000 strings with 1MB default allocation

The result: [You may initialise the string:
string #1
string ...69997
string #69998
string #69999
string #70000], len=1038924 bytes

Try the normal concat(y)?
Fa is a musical note to play with CL

daydreamer

Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz
16 ms for stringbuilder, 70000 strings with 1MB default allocation
15 ms for stringbuilder, 70000 strings with 1MB default allocation
16 ms for stringbuilder, 70000 strings with 1MB default allocation
15 ms for stringbuilder, 70000 strings with 1MB default allocation
15 ms for stringbuilder, 70000 strings with 1MB default allocation
16 ms for stringbuilder, 70000 strings with 1MB default allocation
15 ms for stringbuilder, 70000 strings with 1MB default allocation
15 ms for stringbuilder, 70000 strings with 1MB default allocation
15 ms for stringbuilder, 70000 strings with 1MB default allocation
15 ms for stringbuilder, 70000 strings with 1MB default allocation

The result: [You may initialise the string:
string #1
string ...69997
string #69998
string #69999
string #70000], len=1038924 bytes

Try the normal concat(y)?
This may take a while...
11 s for normal concatenation, 70000 strings

The result: [You may initialise the string:
string #1
string ...69997
string #69998
string #69999
string #70000], len=1038924 bytes

nice Jochen :thup:
now I got curious how fast SSE special material(8characters string)+items(8characters string) randomly would be in a 1MB loop?

my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding