TStringList vs array of String vs TArrayOfString

7.5k views Asked by At

I am refactoring an Inno Setup project and something that isn't very clear to me is the use of TArrayOfString , array of String and TStringList. What are the differences of those three types ? As far as i can see there seems to be no difference in the use of it. All three store strings and i can get a stored string by using the array\list like this: arrayName[i].

Is one faster or is it regarded as bad coding when one of those is used ? I hope somebody can bring clarity to me in this matter.

1

There are 1 answers

2
TLama On BEST ANSWER

1. Difference

The TArrayOfString type is an alias for array of string, so they equals (you can see it here in the source code). The TStringList class is an indexed string collection class, whose storage is an array of records internally. But there's a big difference between string array and TStringList class.

The array of string is just an indexed storage for string elements, whilst the TStringList class is a collection class providing options and methods for several content handling tasks (like e.g. eliminating duplicates, sort, search, etc.).

2. Performance

If we forget on the methods which TStringList class offers and think about it just as being a storage, then we must focus on the way how the string elements will be added to that storage in the application when we want to compare performance.

Generally, an array type will be faster as long as you don't resize the array frequently, e.g. this is not efficient for adding a single element when called frequently:

procedure AddSingleElement(var A: array of string; const S: string);
begin
  SetArrayLength(A, GetArrayLength(A) + 1);
  A[High(A)] := S;
end;

That's because the memory which is holding the array is reallocated. And that costs some time. But you can prevent this bottleneck if you'll set your array length less frequently. Ideal situation is when you set the array length to the target length only once (which requires to know the element count in advance of course).

Another option to improve the above code (when you don't know the count of the elements in advance) is pre-allocating the array length by a few elements. That will decrease the number of reallocations, but also requires from you to remember and operate with the length which is meant to be the logical, actual array length. And that's what the TStringList class internally does for you when you're adding items.

If you add an item to a TStringList object, the string list checks whether has enough space for it, and if not, it increases the length of its internal array by the few elements (by which eliminates the described reallocation performance problem).

But it's not as critical as it sounds and you would notice performance problems if you were operating on very long arrays with very long strings (in thousands, possibly hundreds of thousands elements of really long strings). I don't want to be specific in numbers here simply because that's not what you should ever need in a setup application, I think.

3. Conclusion

To sum up, arrays are faster storage, but you should avoid their frequent resizing. If you really care that much about performance, allocate their size only once (if you know the number of elements in advance), or at least less frequently by more elements (which requires more coding).

The TStringList class loses this performance race (just because it's a wrapper around an array), but it quite effectively resizes its internal storage when you're adding items one by one (without the need of coding this by yourself for an array).

4. Rule of thumb

As a rule of thumb I would suggest using arrays when you know the number of elements in advance, or when you won't frequently change their length. String list when you cannot fulfil that, or when you need some of their built-in content handling routines.