4

Is it somewhere documented the performance characteristics of ImmutableList<T>? I'm interested in the asymptotic complexity (big-O). The msdn link doesn't reveal much.

I have known Add and this[] are both O(log n) from this article, but I want to know also about Remove and Insert.


I would also love to see if possible the complexities of the entire types in the newly introduced System.Collections.Immutable namespace.

nawfal
  • 70,104
  • 56
  • 326
  • 368
  • How does O complexity help you? Wouldn't it be simpler and more telling to just use a benchmark that should be close enough to your actualy use case? Complexity completely ignores most of the real issues in a real computer and will rarely give you a realistic estimate of the production behaviour. Does it really help you that an algorithm is `O(log n)` if you spend all of that time waiting for cache misses to resolve? It's not really useful without also considering the constant costs etc. All in all, what answer do you expect to get when you ask for big-O? – Luaan Jul 16 '14 at 12:04
  • @Luaan it helps me in all those scenarios where knowing about big-O of any collection structure is ever useful. Developers do need to know it, it's always documented by API. For a practical answer, the theoretical knowledge serves as a rule of thumb in deciding the right structure before it becomes a bottleneck. Say help me choose between ImmutableList and ImmutableArray both of which *does* the same thing. – nawfal Jul 16 '14 at 12:15
  • If I dont have scaling beforehand in my mind, my alternatives to code are: 1)ignore damn performance thing, just code, and see to it later if situation warrants; 2)benchmark every alternative for every time I require in a project --- both of which I consider poor. Instead knowing the complexity serves as decent middle-approach. – nawfal Jul 16 '14 at 12:17

1 Answers1

2

Well, based on some examination of the code, I'd expect RemoveAt (Remove has to find the item first) and Insert to be pretty much the same as Add. The basic principle is the same. The thing I'd be more worried about is the pattern of memory usage and things like that - if you use a few ImmutableLists side-by-side and do a lot of adding and removing, I'd expect you might quickly run into data locality issues, which would cause your performance to plummet. AddRange is mostly a shortcut, it really only calls a bunch of Node.Adds anyway, saving some overhead, but not much. There's also a lot of recursion.

ImmutableArray would not cause that, because it always creates a whole new array and copies the old array over. So it will cause a lot of memory copying and allocations / collections, but it will also be more stable performance-wise - access time doesn't change with usage, and there aren't even any shortcuts when modifying the array, you always have to copy all the items. This also means that adding multiple items simply has to be done with AddRange - the performance difference will be enormous. Add is internally implemented using Insert, so it's the same thing at the moment. In other words, all the change operations are o/O(n), while read is o/O(1).

All in all, ImmutableList is more concerned about frequent changes and sacrifices read performance, while ImmutableArray is mostly useful for a lot of reads, and relatively few changes.

Luaan
  • 62,244
  • 7
  • 97
  • 116