The practical difference between Erlang cards: remove / 2 and cards: no / 2

Checking the documentation for one of the new functions of R17 , the card, led me to the cards: remove / 2 and maps: without / 2. The only clear difference that I see is that remove / 2 accepts one key and returns it without a card , where without / 2 it takes a list and returns a completely new card that does not contain the keys listed.

22> M1 = #{foo => bar, spam => eggs}. #{foo => bar,spam => eggs} 23> M2 = maps:without([foo], M1). #{spam => eggs} 24> M3 = maps:remove(foo, M1). #{spam => eggs} 25> M1. #{foo => bar,spam => eggs} 26> M2. #{spam => eggs} 27> M3. #{spam => eggs} 

What is the practical impact of this? I can appreciate not wanting to create copies of memory from giant cards in memory without / 2, but why not delete / 2 to accept the list? I assume that there is a performance-oriented reason why these two functions exist the way they do, but I am confused when I want to use them one above the other in most situations (this means that I do not think that saving giant cards - overall a good idea).

+2
source share
1 answer

The first thing about cards is that the implementation may change. As Fred Hebert wrote in, learn about some of the Erlang Chapter cards : β€œThe OTP team respects the old slogan: first make it work, and then do it beautifully, and only if you need to, do it quickly.” Therefore, it does not depend too much on this answer.

Currently, maps:without/2 implemented as follows:

 without(Ks, M) when is_list(Ks), is_map(M) -> maps:from_list([{K,V}||{K,V} <- maps:to_list(M), not lists:member(K, Ks)]). 

As you can see, it iterates over the whole map. It converts it to a list, deletes the keys, and converts them back to a card. Not very effective, but, as I said: this may change in the future.

The maps:remove/2 function is NIF, which means it is written in C and takes advantage of the internal representation. Speaking of this ... During Stockholm Erlang Factory 2013, Kenneth Lundin mentioned the internal representation of maps ( http://vimeo.com/69950294 ). In fact, there are two of them (slices from conversations with which I am associated).

maps internal representation 1

This is for a small number of keys. In this view, a set of values ​​has a pointer to a set of keys, which means that if you change the value, but the key keys will be split. Keys are also sorted. The second, for large numbers of keys, is as follows:

enter image description here

So, this is a tree, which means that if, for example, you delete a key in the right subtree, your new card can split the entire left subtree. To get clearer information about immutable data structures, you can refer to wikipedia ErlangVM should transparently switch between these views as necessary.

To answer your question. If you want to delete one key, use maps:remove/2 , if you want to remove several keys, use maps:without/2 , because it would be cheaper to create a new map instead of managing the old one.

+7
source

Source: https://habr.com/ru/post/1272797/


All Articles