Skip to content

Limiting String Allocations

Problem

Your code is performance sensitive and needs to make your String concatenation code as fast as possible.

Solution

Replace any usage of String.add with String.append. Going from code like:

let output = file_name + ":" + file_linenum + ":" + file_linepos + ": " + msg

to String.append where we preallocate the memory needed to hold our final string.

let output = recover String(file_name.size()
  + file_linenum.size()
  + file_linepos.size()
  + msg.size()
  + 4) end

output.append(file_name)
output.append(":")
output.append(file_linenum)
output.append(":")
output.append(file_linepos)
output.append(": ")
output.append(msg)
output

Discussion

If you want to make your Pony code go fast (and who doesn’t want to go fast?), there are two simple steps you can take that will get you a lot of rewards: reducing the number of objects you create and reducing the number of memory allocations. Our solution does both.

While String.add can be very convenient, it’s a bit of a dog performance wise.

let output = file_name + ":" + file_linenum + ":" + file_linepos + ": " + msg

will create a new String and allocate memory for it on each +. In the case of our example, that’s six objects that get created and six different memory allocations. Our solution addresses both these issues. First,

let output = recover String(file_name.size()
  + file_linenum.size()
  + file_linepos.size()
  + msg.size()
  + 4) end

allocates all the memory it is going to need in one go; cutting our memory total allocations by five. Then by using append

output.append(file_name)
output.append(":")
output.append(file_linenum)
output.append(":")
output.append(file_linepos)
output.append(": ")
output.append(msg)
output

we don’t create any additional objects.

All told, by switching from String.add to String.append, drop down to a single memory allocation and a single object being created. Replacing a single use of + with append isn’t going to get you much, however, if the code you are replacing is called a lot, it’s going to be a huge win. In the case of our solution above, we took the code from the Pony logger package. Given how often logging methods get called, switching from + to append has a huge impact.