I've been pretty vague which probably isn't very helpful so I'll try to be a bit more precise: for a mutable implementation it's quadratic in the number of times render is called over the lifetime of the component; for an immutable implementation it's quadratic in the number of comparisons (inside shouldComponentUpdate) over the same lifetime. You can generalize both operations to "process component when building the component tree".
Each time you add an item to a list of size n, it needs to process the previous n items. This forms the series 1+2+...+(n-1)+n, which is (n^2+n)/2.
Obviously a reference comparison is a lot quicker than a render, so you get big speed wins using immutablejs that are definitely worth it, but it's still O(n^2) components processed.
A component being processed via returning false from shouldComponentUpdate is very very different from a component being processed by running the render method and then doing a diff, so that is not a good model.
Each time you add an item to a list of size n, it needs to process the previous n items. This forms the series 1+2+...+(n-1)+n, which is (n^2+n)/2.
Obviously a reference comparison is a lot quicker than a render, so you get big speed wins using immutablejs that are definitely worth it, but it's still O(n^2) components processed.