<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><br></div><div>Well, reading from ETS does impose a copy operation, but this is just as efficient (as far as it goes) as message passing, which also copies. Exactly the same copy operation is used, in fact.</div><div><br></div><div>And just as with message passing, if you are using binaries, they may be passed by reference instead, as has already been pointed out.</div><div><br></div><div>Given that term copying is central in message passing and GC, as well as in ETS, a lot of time has been invested in optimizing it*. The Erlang VM does it well, but of course, copying is always copying - the cost will be relative to the size of the data, and the emulator must traverse the term in order to know what's in it.</div><div><br></div><div>The actual code is in $ERL_TOP/erts/emulator/beam/copy.c (copy_struct()), or:</div><div><br></div><div><a href="https://github.com/erlang/otp/blob/master/erts/emulator/beam/copy.c#L191">https://github.com/erlang/otp/blob/master/erts/emulator/beam/copy.c#L191</a></div><div><br></div><div>Another potential performance issue with ETS tables is locking, if you have many cores. Again, this is an area that the ERTS team is working hard on, so it gets better and better. However, shared data structures are notoriously hard to manage as the core count grows.</div><div><br></div><div>Bottom line: it's good to be aware of cost factors, but you won't know how fast or slow it is in reality, until you measure (which you did!). ETS tables are fast enough for most purposes. :)</div><div><br></div><div>BR,</div><div>Ulf W</div><div><br></div><div>* The garbage collector uses its own copying techniques, since it doesn't have to be limited to copying one term at a time, and also _must_ preserve subterm sharing.</div><br><div><div>On 11 Jan 2012, at 12:15, Martin Dimitrov wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>I thought this is a lame question so I posted it on StackOverflow<br>(<a href="http://stackoverflow.com/questions/8811430/retrieval-of-data-from-ets-table">http://stackoverflow.com/questions/8811430/retrieval-of-data-from-ets-table</a>)<br>so not to bother the list but there aren't many replies.<br><br>Here it is my observation:<br><br>I know that lookup time is constant for ETS tables. But I also heard<br>that the table is kept outside of the process and when retrieving data,<br>the data needs to be moved to the process heap. So, this is expensive.<br>But then, how to explain this:<br><br>1> {ok, B} = file:read_file("IMG_2171.JPG").<br>{ok,<<255,216,255,225,63,254,69,120,105,102,0,0,73,73,42,<br>      0,8,0,0,0,10,0,14,1,2,0,32,...>>}<br>2> size(B).<br>1986392<br>3> L = binary_to_list(B).<br>[255,216,255,225,63,254,69,120,105,102,0,0,73,73,42,0,8,0,0,<br> 0,10,0,14,1,2,0,32,0,0|...]<br>4> length(L).<br>1986392<br>5> ets:insert(utilo, {a, L}).<br>true<br>6> timer:tc(ets, match, [utilo, {a, '$1'}]).<br>{106000,<br> [[[255,216,255,225,63,254,69,120,105,102,0,0,73,73,42,0,8,0,<br>    0,0,10,0,14,1,2|...]]]}<br><br>It takes 106000 microseconds to retrieve 1986392 long list which is<br>pretty fast, isn't it?<br>I also tried it from a module and the result is the same.<br><br>Best regards,<br><br>Martin<br><br><br>_______________________________________________<br>erlang-questions mailing list<br><a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>http://erlang.org/mailman/listinfo/erlang-questions<br></div></blockquote></div><br></body></html>