[Gambas-user] Is the &= efficient?

Tobias Boege taboege at gmail.com
Tue Mar 5 21:56:12 CET 2019


On Tue, 05 Mar 2019, Cedron Dawg wrote:
> It has been mentioned in the past that Gambas doesn't have garbage collection, that objects are allocated in place.  In regular BASICS, and Java, etc, when a string append is performed, space for the new string is created, the old string copied, and the new string copied at the end.
> 
> So the question is, if one is appending a whole block of strings like this:
> 
>         x &= "long string constant"
>         x &= "long again " & maybewith & "some replacement termst"
>         .
>         .
>         .
>              
> Is it better to allocate a memory area and print to the memory instead?
> 
> Syntactically, I think the former is cleaner looking, but if there is a performance hit, that is not worth it.  The two variations are easily interchangeable via search and replace, so is not something I need to know immediately, but I'd like to know which is better.
> 
> Not worth a deep dive into the code yet though.
> 

A string in Gambas is a base pointer, an index into it and a length.
This implies that concatenation has to realloc and copy. (It also
means by contrast that operations like Mid$() are very cheap.)

You can observe this with a test program like this:

  Public Const Lipsum As String = ""
  "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, "
  ' around 600 bytes of etc.

  Public Sub Main()
    Dim s As String

    If Args.Count < 2 Then Error.Raise("Need number of iterations")
    For i As Integer = 0 To CInt(Args[1])
      s &= Lipsum
    Next
  End

and valgrind:

  $ valgrind -- gbx3 -- 0 2>&1 | grep -o "total heap usage.*"
  total heap usage: 338 allocs, 338 frees, 75,382 bytes allocated
  $ valgrind -- gbx3 -- 10 2>&1 | grep -o "total heap usage.*"
  total heap usage: 348 allocs, 348 frees, 115,222 bytes allocated
  $ valgrind -- gbx3 -- 100 2>&1 | grep -o "total heap usage.*"
  total heap usage: 438 allocs, 438 frees, 3,134,134 bytes allocated
  $ valgrind -- gbx3 -- 1000 2>&1 | grep -o "total heap usage.*"
  total heap usage: 1,338 allocs, 1,338 frees, 296,614,134 bytes allocated

While the numbers of allocations line up perfectly with the Gambas
code that you see, you can guess from those samples regarding "bytes
allocated" that the cumulative memory usage grows almost quadratically
in the number of iterations, which may at least count as some evidence
for a plain realloc and copy.

Regards,
Tobi

-- 
"There's an old saying: Don't change anything... ever!" -- Mr. Monk


More information about the User mailing list