[erlang-questions] Question about implementation

79 views
Skip to first unread message

Max Lapshin

unread,
Sep 10, 2012, 10:27:20 AM9/10/12
to Erlang-Questions Questions
For example I have such gen_server:

-record(state,
field1,
field2,
field3,
counter = 0
}.



handle_info(incr, #state{counter = Counter} = State) ->
{noreply, State#state{counter = Counter + 1}};


Will here whole #state{} be deep-copied with new Counter +1 field, or
it is possible to guess, that here optimization is possible and just
"edit" counter field in existing tuple?

Is it possible to understand by erlang source code, that State is no
longer referenced anywhere to avod large allocation and free?
_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions

Lukas Larsson

unread,
Sep 10, 2012, 12:08:26 PM9/10/12
to Max Lapshin, Erlang-Questions Questions
Hello,

Only the tuple which is the record and the immidiates (i.e. small int,
atom, pid, ref etc) will be copied. All other parts use pointers
internally and the same pointers will be copied into the correct
places within the tuple. So in this case a new 6 word memory block
will be created and filled with the atom undefined and finally the new
counter.

I think that the compiler does some optimization based on updating
tuples within the same function body, though I've forgotten what it is
it does.

Hope that makes sense.

Lukas

Max Lapshin

unread,
Sep 10, 2012, 12:14:22 PM9/10/12
to Lukas Larsson, Erlang-Questions Questions
On Mon, Sep 10, 2012 at 8:08 PM, Lukas Larsson
<lu...@erlang-solutions.com> wrote:
> Hello,
>
> Only the tuple which is the record and the immidiates (i.e. small int,
> atom, pid, ref etc) will be copied. All other parts use pointers
> internally and the same pointers will be copied into the correct
> places within the tuple. So in this case a new 6 word memory block
> will be created and filled with the atom undefined and finally the new
> counter.
>

Thank you!


It is right what I wanted to hear. No deep copy, only reallocation of
top-level tuple.

Daniel Dormont

unread,
Sep 10, 2012, 1:35:18 PM9/10/12
to Lukas Larsson, Erlang-Questions Questions
On Mon, Sep 10, 2012 at 12:08 PM, Lukas Larsson <lu...@erlang-solutions.com> wrote:
Hello,

Only the tuple which is the record and the immidiates (i.e. small int,
atom, pid, ref etc) will be copied. All other parts use pointers
internally and the same pointers will be copied into the correct
places within the tuple. So in this case a new 6 word memory block
will be created and filled with the atom undefined and finally the new
counter.

I think that the compiler does some optimization based on updating
tuples within the same function body, though I've forgotten what it is
it does.


Max Lapshin

unread,
Sep 10, 2012, 1:36:06 PM9/10/12
to Daniel Dormont, Lukas Larsson, Erlang-Questions Questions

Richard O'Keefe

unread,
Sep 10, 2012, 5:53:41 PM9/10/12
to Max Lapshin, Erlang-Questions Questions

On 11/09/2012, at 2:27 AM, Max Lapshin wrote:
> Will here whole #state{} be deep-copied with new Counter +1 field,

No it will be *shallow*-copied. You get a new #state term, but
any fields that are not changed will not themselves be copied.
> or
> it is possible to guess, that here optimization is possible and just
> "edit" counter field in existing tuple?
>
> Is it possible to understand by erlang source code, that State is no
> longer referenced anywhere to avod large allocation and free?

For the special case of states passed around loops of private functions
it ought to be possible to infer that a function argument is not shared
but for exported functions it is not possible because it depends on the
callers.

Loïc Hoguin

unread,
Sep 14, 2012, 7:45:58 PM9/14/12
to Daniel Dormont, Lukas Larsson, Erlang-Questions Questions
Hello,

On 09/10/2012 07:35 PM, Daniel Dormont wrote:
>
> On Mon, Sep 10, 2012 at 12:08 PM, Lukas Larsson
> <lu...@erlang-solutions.com <mailto:lu...@erlang-solutions.com>> wrote:
>
> Hello,
>
> Only the tuple which is the record and the immidiates (i.e. small int,
> atom, pid, ref etc) will be copied. All other parts use pointers
> internally and the same pointers will be copied into the correct
> places within the tuple. So in this case a new 6 word memory block
> will be created and filled with the atom undefined and finally the new
> counter.
>
> I think that the compiler does some optimization based on updating
> tuples within the same function body, though I've forgotten what it is
> it does.
>
>
> This bit?
> http://www.erlang.org/doc/efficiency_guide/commoncaveats.html#id61731

Is the optimization applied automatically to records?

--
Loïc Hoguin
Erlang Cowboy
Nine Nines
http://ninenines.eu

Robert Virding

unread,
Sep 16, 2012, 5:10:33 PM9/16/12
to Loïc Hoguin, Lukas Larsson, Erlang-Questions Questions
Yes. There are a few rules which need to be followed so that the compiler can safely do this optimisation, and generally doing multiple updates to a record *in one go* will satisfy these rules. So

X1 = X0#r{a=foo(),b=bar(),c=baz()},

will be optimised, while

X1 = X0#r{a=foo()},
X2 = X1#r{b=bar()},
X3 = X2#r{c=baz()},

will not. It always tries to do this optimisation but it is generally seldom safe to do it.

Robert

Reply all
Reply to author
Forward
0 new messages