UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: Improve memory performance

Forums > Swift

Currently I have a log of activities that are simply concatinated to a string within a a scrollable TextView. As the log grows, this becomes very clumsy as the whole string gets recreated with each new line.

If I changed this to an array of lines, does array append require the whole array to be regenerated or does it just use (effectively) pointers?

The log can become very long, 1,000s of lines.

PS - similarily, in an editor, is the use of a string favoured over the use of an array of strings? An array of strings would be the normal case in C.

2      

Using Playground on a M1 iPad Pro I ran a test with 10 million string additions.

In one test, I concatinated 10 million strings together, adding the latest to the already collected string.

In the other test, I added a new string as a new row in an array of strings.

Both were very fast with the array test being generally 13% faster than the concatination.

In further reading, it appears that Swift uses a "write on change" approach with strings and arrays. Since my tests didn't access the string collection nor elements, I think my tests are flawed. That is to say, Swift took a short cut to process the loops that wouldn't be the case if I was displaying the string or array in a scrollable Text View.

Does any of this make sense?

3      

Brilliant analysis!

What on earth are you doing where you might collect 10 million (!) strings. I can't even!

Michael: "Hey M1 chip! Here are 10 million strings for you to concatenate! Ready, steady, GO!"
M1 Chip: Yawn

2      

From the docs:

Because arrays increase their allocated capacity using an exponential strategy, appending a single element to an array is an O(1) operation when averaged over many calls to the append(_:) method. When an array has additional capacity and is not sharing its storage with another instance, appending an element is O(1). When an array needs to reallocate storage before appending or its storage is shared with another copy, appending is O(n), where n is the length of the array.

Complexity: O(1) on average, over many calls to append(_:) on the same array.

Does this answer your question?

3      

In further reading, it appears that Swift uses a "write on change" approach with strings and arrays.

Do you mean "copy on write"? All that means is that if you have, say an array of 10 million Strings and create a copy of it, behind the scenes Swift doesn't actually make a copy until/unless you change something in the copy. Otherwise it just stores a reference to the original storage.

So...

let a1 = [...10 million Strings...]  //big-ass array allocated
var a2 = a1 //no allocation here
a2.append("one more string") //NOW we allocate a new array and append the additional String

3      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.