There is a slight misunderstanding in the question. That post does not mean shallow comparison is expensive.
Here's a brief context before I answer:
The usual behaviour of a React Component is to re-render the component whenever its props or state changes. Now the change does not necessarily mean there is a change in values, instead it could also be same set of values passed again. This usually happens when its Parent Component either refreshes the state or re-renders, due to this, Child Components unnecessarily re-render every time.
To avoid unnecessary re-renders, what React team thought of is to perform a "shallow comparison logic" between new value change (i.e new props/state) and existing values (current props/state) to quickly decide if the component should perform a re-render. This saves the overhead of re-rendering the component, hence the performance boost.
Now coming to the misunderstanding of the post what I mentioned earlier:
The logic of "shallow comparison" in React is done by iterating through the keys of new-values(say A) and check its existence in previous-values(say B) and then it performs shallow comparison on each value of the key present in A and B. So complexity would be -- ~O(n(A)*n(B)). Once this process is performed, then there forms a decision whether to render the component or not.
Now, what the post meant is that if you make every component as pure, then you'd add an overhead of shallow comparison for every component on every re-render instead of directly re-rendering it blindly (usual behaviour). So, the point is, make sure your Component is critical enough to make it PureComponent so that you can avoid its expensive re-renders.
Cheers!