Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Lambda function capturing and memory usage

Reply
Thread Tools

Lambda function capturing and memory usage

 
 
Juha Nieminen
Guest
Posts: n/a
 
      04-22-2012
I was wondering: Does memory usage increase every time that a lambda
function captures variables, especially if it's then stored into a
std::function wrapper?

This question came up when I was thinking about a rather functional
example usage of lambdas, like this:

std::function<int(int)> multiplierFunction(int multiplier)
{
return [multiplier](int value) { return value * multiplier; };
}

The above function could be used eg. like:

auto doubler = multiplierFunction(2);
auto tripler = multiplierFunction(3);
auto nMultiplier = multiplierFunction(n);

std::cout << doubler(5) << " " << tripler(x) << " "
<< nMultiplier(y) << "\n";

The values '2', '3' and 'n' have to be stored somewhere for (at least)
as long as 'doubler', 'tripler' and 'nMultiplier' exist. Where are they
stored and for how long? (Are they freed immediately when those variables
go out of scope? How?)

What worries me is the possible memory usage if the above function is
used eg. in a loop, like:

for(int i = 0; i < 1000000; ++i)
{
auto f = multiplierFunction(i);
std::cout << f(2) << "\n";
}

Does memory usage increase a million-fold, or is the memory recycled after
each loop?


 
Reply With Quote
 
 
 
 
MelissA
Guest
Posts: n/a
 
      04-22-2012
On 22 Apr 2012 12:21:06 GMT
Juha Nieminen <(E-Mail Removed)> wrote:

>
> for(int i = 0; i < 1000000; ++i)
> {
> auto f = multiplierFunction(i);
> std::cout << f(2) << "\n";
> }
>
> Does memory usage increase a million-fold, or is the memory recycled
> after each loop?
>
>


I have tested this code on Ubuntu 11.10 g++ 4.6.1 and memory does
not increase.

 
Reply With Quote
 
 
 
 
Alain Ketterlin
Guest
Posts: n/a
 
      04-22-2012
Juha Nieminen <(E-Mail Removed)> writes:

> I was wondering: Does memory usage increase every time that a lambda
> function captures variables, especially if it's then stored into a
> std::function wrapper?


Yes, some memory is used to keep the captures.

> std::function<int(int)> multiplierFunction(int multiplier)
> {
> return [multiplier](int value) { return value * multiplier; };
> }
>
> The above function could be used eg. like:
>
> auto doubler = multiplierFunction(2);
> auto tripler = multiplierFunction(3);
> auto nMultiplier = multiplierFunction(n);
> std::cout << doubler(5) << " " << tripler(x) << " "
> << nMultiplier(y) << "\n";
>
> The values '2', '3' and 'n' have to be stored somewhere for (at least)
> as long as 'doubler', 'tripler' and 'nMultiplier' exist.


You are absolutely right.

> Where are they stored and for how long? (Are they freed immediately
> when those variables go out of scope? How?)


The code is generated once and for all (per template), and captured data
is stored in an instance of a compiler-generated class. (At least,
that's how I would implement it.)

> What worries me is the possible memory usage if the above function is
> used eg. in a loop, like:
>
> for(int i = 0; i < 1000000; ++i)
> {
> auto f = multiplierFunction(i);
> std::cout << f(2) << "\n";
> }
>
> Does memory usage increase a million-fold, or is the memory recycled after
> each loop?


The f object goes out of scope at each iteration, so there is no
accumulation. If you were to place these functions inside an array, then
it would probably fill up some memory...

-- Alain.
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      04-22-2012
Alain Ketterlin <(E-Mail Removed)-strasbg.fr> wrote:
> The code is generated once and for all (per template), and captured data
> is stored in an instance of a compiler-generated class. (At least,
> that's how I would implement it.)


I'm assuming that when you are using lambda functions directly, like

auto func = [multiplier](int value) { return value * multiplier; };

then the type of 'func' will be internally something very similar to a
struct containing the value of 'multiplier' as a member, and the lambda
operating on this "struct" exactly is if it were its member function.
Thus, this "struct" is bound to the scope where it's created in the
exact same way as any old-fashioned functor would be.

*However*, std::function cannot have any such struct as a member.
The type of eg. "std::function<int(int)>" never changes regardless of
which kind of lambda is assigned to it, and how many variables might have
been captured. (A clear sign of this is that you can use such
std::function<int(int)> objects in non-templated code.) In this case the
captured variables cannot be stored locally on the stack like they can
when dealing with lambdas directly. They have to be stored somewhere else.

Does std::function keep the "capture struct" on the heap? Does it manage
it like a smart pointer would? Or does it do something even smarter?
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      04-24-2012
Juha Nieminen <(E-Mail Removed)> wrote:
> Does std::function keep the "capture struct" on the heap? Does it manage
> it like a smart pointer would? Or does it do something even smarter?


So nobody knows the answer to this question?
 
Reply With Quote
 
Alain Ketterlin
Guest
Posts: n/a
 
      04-24-2012
Juha Nieminen <(E-Mail Removed)> writes:

> Juha Nieminen <(E-Mail Removed)> wrote:
>> Does std::function keep the "capture struct" on the heap? Does it manage
>> it like a smart pointer would? Or does it do something even smarter?


That was my guess...

> So nobody knows the answer to this question?


I don't, but would appreciate any info on how this is implemented.

-- Alain.
 
Reply With Quote
 
cartec69@gmail.com
Guest
Posts: n/a
 
      04-24-2012
On Tuesday, April 24, 2012 5:47:03 AM UTC-5, Juha Nieminen wrote:
> Juha Nieminen <(E-Mail Removed)> wrote:
> > Does std::function keep the "capture struct" on the heap? Does it manage
> > it like a smart pointer would? Or does it do something even smarter?

>
> So nobody knows the answer to this question?


std::function has to be polymorphic, so in general it needs to copy to the heap. The standard does not mandate that behavior, however, and even encourages implementors to optimize common cases (function pointer, member function pointer and object).
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Type of lambda function returning a lambda function... Haochen Xie C++ 4 03-17-2013 11:23 PM
Lambda function capturing and memory usage Juha Nieminen C++ 1 04-22-2012 12:22 PM
C++0x lambda and capturing computed values Sohail Somani C++ 5 05-07-2009 07:58 PM
lambda vs non-lambda proc Steve Dogers Ruby 1 03-30-2009 10:11 PM
Re: Lambda as declarative idiom (was RE: what is lambda used for inreal code?) Roman Suzi Python 13 01-07-2005 09:33 PM



Advertisments