When using immutable dictionaries in F# , how much overhead is there when adding / removing entries?
Will it treat entire buckets as immutable and clone those and only recreate the bucket whos item has changed?
Even if that is the case, it seems like there is alot of copying that needs to be done in order to create the new dictionary(?)
I looked at the implementation of the F#
Map<K,V>type and I think it is implemented as a functional AVL tree. It stores the values in the inner nodes of the tree as well as in the leafs and for each node, it makes sure that |height(left) – height(right)| <= 1.I think that the both average and worst-case complexities are
O(log(n)):Insert we need to clone all nodes on the path from the root to the newly inserted element and the height of the tree is at most
O(log(n)). On the “way back”, the tree may need to rebalance each node, but that’s also onlyO(log(n))Remove is similar – we find the element and then clone all nodes from the root to that element (rebalancing nodes on the way back to the root)
Note that other data-structures that don’t need to rebalance all nodes from the root to the current one on insertion/deletion won’t be really useful in the immutable scenario, because you need to create new nodes for the entire path anyway.