StringBuffer in Dart

infiniteoverflow

Aswin Gopinathan

Posted on September 28, 2021

StringBuffer in Dart

Imagine you are building the next Billion Dollar app 💵 that has a lot of innovative features which are new to the tech world. But your app crashes a lot! Further investigation proved that the code you wrote for the app is not optimized.
Uff ! Thats a bummer 😐. What would you do?

Well, you call me 📲 !
Nahh, just open this tutorial.✅

Most of the apps out there incorporate String Concatenation in some or the other way. It could be to join the First Name and Last Name of a person, or get the list of cities the user has travelled this year, and the list goes on.

Most of the developers including me, follow one approach for string concatenation, ie, using the '+' operator.
Here is a basic example to illustrate what i meant:

String? firstName = "Aswin";
String? lastName = "Gopinathan";

String? fullName = firstName + " " + lastName;
Enter fullscreen mode Exit fullscreen mode

This is the most typical approach, and it's easier too. But this approach comes with a price.

And the price is memory !!

Let's see another example where we concatenate strings from a List:

List<String> cities = ["Bangalore","Mumbai","Delhi","Chennai"];

String finalCities = "";

for(String city in cities) {
  finalCities += (city+' ');
}

print(finalCities);
Enter fullscreen mode Exit fullscreen mode

The output will be:

Bangalore Mumbai Delhi Chennai 
Enter fullscreen mode Exit fullscreen mode

You might have read that Strings in dart are immutable. But, we just updated finalCities multiple times. How is it even possible?

Well, the answer to this magic is that every time we concatenate a new string, the compiler allocates a new memory for the resultant string, and the garbage collector is called to de-allocate the previous memory location.

So literally the garbage collector is called for every item you concatenate, and for each of those iterations a new memory location is assigned !!

Finding it hard to believe? Its okay, i understand.

Let's do one thing. Write this line of code inside the for loop from the previous code snippet:

print(identityHashCode(finalCities));
Enter fullscreen mode Exit fullscreen mode

This line of code prints the hashcode of the memory address of the variable finalCities.

What do you see? The output should be like this:

260230835
327507326
116916136
283166850
Enter fullscreen mode Exit fullscreen mode

The values may differ for you.

So, it is pretty clear from this that the variable finalCities uses different memory location in every iteration.

But dont worry, if i bummed you out with this, i will fix it too !!

Enter : StringBuffer 🥁🥁

Me : "Welcome StringBuffer to this article"
StringBuffer : "Ahoy ! Let me introduce myself. My name is StringBuffer. I take care of the mess that my ancestor String creates. You know he is pretty old-school.
Me : "I know but he is still one of the best. So without any further delays, let me tell everyone how you work."

So, as the official dart docs says :
"A class for concatenating strings efficiently. Allows for the incremental building of a string using write() methods. The strings are concatenated to a single string only when toString is called."

Let me break that down for you.

StringBuffer is a class that lets you concatenate string efficiently. Duh! you just read that above.
Well, how it works is you use the inbuilt method write() to concatenate strings instead of the + operator. But what happens with StringBuffer is that, it stores the string in a buffer and not in a memory location. It uses the memory only when the toString() method is called to create a String object.

Tada! Now you don't have to worry about the memory being allocated every time you concatenate.

See, StringBuffer is a superhero 😎

Well, thats all for the theory part 😉
But don't go yet, let's get our hands dirty. Shall we? 😋

So, lets open a new dart file and start off with the main():

void main() {
  // Enter code here
}
Enter fullscreen mode Exit fullscreen mode

Let's create a StringBuffer object first. We will be using the same List as before:

StringBuffer sb = StringBuffer();

List<String> cities = ["Bangalore","Mumbai","Delhi","Chennai"];
Enter fullscreen mode Exit fullscreen mode

Now, rewrite the for loop as follows:

for(String city in cities) {
  sb.write(city+" ");
  // print(identityHashCode(sb));
}
Enter fullscreen mode Exit fullscreen mode

We use the write() to append new strings to the end. You can uncomment the print() statement to confirm no new memory location is created for every concatenation.

Well, now print the result:

String cityList = sb.toString();
print(cityList);
Enter fullscreen mode Exit fullscreen mode

It is at this point a memory location is created to print the concatenated string.

Wow! Thats really great. Now you have reduced one of the many causes of memory leaks in your app 👏👏.
Now, you are one step closer to releasing that Billion-dollar app.

So, with that i am ending this article. But this is not the actual end. I am still exploring Flutter and Dart and as i learn anything new, i will be back with more articles.

So till then, Bye bye !!! 👋

💖 💪 🙅 🚩
infiniteoverflow
Aswin Gopinathan

Posted on September 28, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related