Range-based loop optimization

Discussion in 'C++' started by Juha Nieminen, May 11, 2012.

  1. Assume that I have something along the lines of:

    //----------------------------------------------------
    struct Something
    {
    std::vector<SomethingElse> aBigVector;
    std::set<FooBar> aBigSet;
    };
    //----------------------------------------------------

    and then I inadvertently do something like this:

    //----------------------------------------------------
    std::vector<Something> container;
    populate(container);

    for(auto element : container)
    // code that does not modify 'element'
    //----------------------------------------------------

    What I *should* have done is, of course, this:

    //----------------------------------------------------
    for(const auto& element : container)
    ...
    //----------------------------------------------------

    Or even just:

    //----------------------------------------------------
    for(auto& element : container)
    ...
    //----------------------------------------------------

    If, however, I mistakenly do it without a reference, will the compiler
    be able to optimize the copying of the large elements if it sees that
    they are not modified in the loop body?

    If the compiler is unable to optimize the copying away, I'm thinking
    that the range-based loop is way too easy to use in an inefficient manner
    by mistake. This is not a very good thing.
     
    Juha Nieminen, May 11, 2012
    #1
    1. Advertising

  2. Juha Nieminen

    Marc Guest

    Juha Nieminen wrote:

    > Assume that I have something along the lines of:
    >
    > //----------------------------------------------------
    > struct Something
    > {
    > std::vector<SomethingElse> aBigVector;
    > std::set<FooBar> aBigSet;
    > };
    > //----------------------------------------------------
    >
    > and then I inadvertently do something like this:
    >
    > //----------------------------------------------------
    > std::vector<Something> container;
    > populate(container);
    >
    > for(auto element : container)
    > // code that does not modify 'element'
    > //----------------------------------------------------
    >
    > What I *should* have done is, of course, this:
    >
    > //----------------------------------------------------
    > for(const auto& element : container)
    > ...
    > //----------------------------------------------------
    >
    > Or even just:
    >
    > //----------------------------------------------------
    > for(auto& element : container)
    > ...
    > //----------------------------------------------------
    >
    > If, however, I mistakenly do it without a reference, will the compiler
    > be able to optimize the copying of the large elements if it sees that
    > they are not modified in the loop body?


    I don't think it is allowed to. Copy elision happens in a very limited
    set of explicitly listed cases, and they are all about omitting a
    temporary when creating a new object, which isn't the case here.

    On the other hand, if your copy constructor has no side effect and is
    simple enough for the compiler to understand, it will optimize and
    remove most of the actions of copying. It depends what is in the body
    of your for loop (if it is empty...), but it would require a very
    clever compiler for a std::set to fall into this category. For
    std::vector<POD>, it seems almost within reach of current compilers.
     
    Marc, May 11, 2012
    #2
    1. Advertising

  3. Juha Nieminen

    Guest

    On Friday, May 11, 2012 6:30:52 AM UTC-5, Juha Nieminen wrote:
    > Assume that I have something along the lines of:
    >
    > //----------------------------------------------------
    > struct Something
    > {
    > std::vector<SomethingElse> aBigVector;
    > std::set<FooBar> aBigSet;
    > };
    > //----------------------------------------------------
    >
    > and then I inadvertently do something like this:
    >
    > //----------------------------------------------------
    > std::vector<Something> container;
    > populate(container);
    >
    > for(auto element : container)
    > // code that does not modify 'element'
    > //----------------------------------------------------
    >
    > What I *should* have done is, of course, this:
    >
    > //----------------------------------------------------
    > for(const auto& element : container)
    > ...
    > //----------------------------------------------------
    >
    > Or even just:
    >
    > //----------------------------------------------------
    > for(auto& element : container)
    > ...
    > //----------------------------------------------------
    >
    > If, however, I mistakenly do it without a reference, will the compiler
    > be able to optimize the copying of the large elements if it sees that
    > they are not modified in the loop body?
    >
    > If the compiler is unable to optimize the copying away, I'm thinking
    > that the range-based loop is way too easy to use in an inefficient manner
    > by mistake. This is not a very good thing.


    I've thought about that also, but probably if an author
    isn't aware of it, someone will catch it in a code review.

    I remember a thread a few months ago about studying code
    from a project. If such an author studied this code --
    http://webEbenezer.net/misc/direct.tar.bz2
    they might notice the use of & in this context and
    investigate it further.

    http://webEbenezer.net
     
    , May 12, 2012
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    46
    Views:
    974
    Antoon Pardon
    Jul 25, 2006
  2. Ravikiran

    Zero Optimization and Sign Optimization???

    Ravikiran, Nov 17, 2008, in forum: C Programming
    Replies:
    22
    Views:
    877
    Thad Smith
    Nov 24, 2008
  3. Johannes Schaub (litb)

    Re: C++0x question: Range-based loop and auto

    Johannes Schaub (litb), Mar 13, 2010, in forum: C++
    Replies:
    3
    Views:
    441
    Alf P. Steinbach
    Mar 14, 2010
  4. Johannes Schaub (litb)

    Range-based for loop and ADL

    Johannes Schaub (litb), Sep 5, 2010, in forum: C++
    Replies:
    2
    Views:
    331
    Johannes Schaub (litb)
    Sep 5, 2010
  5. Isaac Won
    Replies:
    9
    Views:
    391
    Ulrich Eckhardt
    Mar 4, 2013
Loading...

Share This Page