StringBuffer in Dart
Aswin Gopinathan
Posted on September 28, 2021
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;
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);
The output will be:
Bangalore Mumbai Delhi Chennai
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));
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
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
}
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"];
Now, rewrite the for loop as follows:
for(String city in cities) {
sb.write(city+" ");
// print(identityHashCode(sb));
}
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);
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 !!! 👋
Posted on September 28, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.