STL algorithm VS Java loop

Discussion in 'C++' started by Allerdyce.John@gmail.com, Jan 17, 2006.

  1. Guest

    Hi,

    I am trying to compare the amount of work between using STL algorithm
    VS a plain Java loop.

    Let's say the class Rect has 2 attributes: area, and areaPerCent.

    In Java, I just write a plain for loop with a list:
    public static void calculateAreaPerCent(List rectList, float
    containerArea) {
    for (Iterator iter = rectList.iterator(); iter.hasNext();) {
    Rect r = (Rect) iter.next();
    r.areaPerCent = r.area / containerArea;
    }
    }

    And in C++, it is recommded to use STL algorithm instead of a plain
    loop, we need to do this:
    class doloop : public unary_function<Rect*, void>
    {
    public:
    loopthru(float containerArea) : _containerArea(containerArea) { }

    void operator() (Rect* r) {

    r->areaPerCent = r->area /_containerArea;
    }
    private:
    _containerArea;

    };

    void calculateAreaPerCent(vector<Rect*>& rl, float containerArea) {
    for_each (rl.begin(), rl.end(), doloop(containerArea));
    }

    It seems to me the C++ STL algorithm way needs more work. Is that a
    fair comparision? Is there a simpler way? Or I should use a plain C++
    for loop ?

    Thank you.
     
    , Jan 17, 2006
    #1
    1. Advertising

  2. Axter Guest

    wrote:
    > Hi,
    >
    > I am trying to compare the amount of work between using STL algorithm
    > VS a plain Java loop.
    >
    > Let's say the class Rect has 2 attributes: area, and areaPerCent.
    >
    > In Java, I just write a plain for loop with a list:
    > public static void calculateAreaPerCent(List rectList, float
    > containerArea) {
    > for (Iterator iter = rectList.iterator(); iter.hasNext();) {
    > Rect r = (Rect) iter.next();
    > r.areaPerCent = r.area / containerArea;
    > }
    > }
    >
    > And in C++, it is recommded to use STL algorithm instead of a plain
    > loop, we need to do this:
    > class doloop : public unary_function<Rect*, void>
    > {
    > public:
    > loopthru(float containerArea) : _containerArea(containerArea) { }
    >
    > void operator() (Rect* r) {
    >
    > r->areaPerCent = r->area /_containerArea;
    > }
    > private:
    > _containerArea;
    >
    > };
    >
    > void calculateAreaPerCent(vector<Rect*>& rl, float containerArea) {
    > for_each (rl.begin(), rl.end(), doloop(containerArea));
    > }


    You don't need to use a for_each in C++, and you can use the common
    for() loop method.
    Use the fore_each method when you have a generic function, that can be
    used with multiple types.
    Java doesn't have this option, so it's harder to reuse code in Java.
    In C++ we have more options, and therefore can do it in a manner that
    is best for a paticular application.

    >
    > It seems to me the C++ STL algorithm way needs more work. Is that a
    > fair comparision?


    No. Since you're comparring apples and oranges. You can use nearly
    the same syntax used in Java, and you have more efficient code.


    > Is there a simpler way? Or I should use a plain C++ for loop ?

    You should be using the plain C++ loop, unless you have a generic
    function.

    Moreover, you should avoid using pointers unless you're sure you have
    to.
    In Java, everything is basically a pointer.
    In C++, you don't need to use pointers, unless you're using abstract
    types.

    If Rect is not an abstract type, than there's no need to use a vector
    of pointers.
    vector<Rect> vRect;

    If Rect is an abstract type, than you should use a smart pointer,
    instead of a raw dummy pointer.
    vector<boost::shared_ptr<Rect> > vRect;
    or
    vector<cow_ptr<Rect> > vRect;

    See following link for cow pointer:
    http://code.axter.com/cow_ptr.h
    http://code.axter.com/copy_ptr.h

    And check out the boost library for shared_ptr.
     
    Axter, Jan 17, 2006
    #2
    1. Advertising

  3. Markus Moll Guest

    Hi

    Axter wrote:

    > You don't need to use a for_each in C++, and you can use the common
    > for() loop method.
    > Use the fore_each method when you have a generic function, that can be
    > used with multiple types.


    Why?
    I don't see any relation...

    > Java doesn't have this option, so it's harder to reuse code in Java.


    Java 5 knows generics, btw...

    >> It seems to me the C++ STL algorithm way needs more work. Is that a
    >> fair comparision?

    >
    > No. Since you're comparring apples and oranges. You can use nearly
    > the same syntax used in Java, and you have more efficient code.


    More efficient? I doubt that for_each(begin,end,action) boils down to
    anything else but for(For i=begin; i!=end; ++i) action(*i);

    Markus
     
    Markus Moll, Jan 17, 2006
    #3
  4. Alan Johnson Guest

    Alan Johnson, Jan 17, 2006
    #4
  5. Axter Guest

    Markus Moll wrote:
    > Hi
    >
    > Axter wrote:
    >
    > > You don't need to use a for_each in C++, and you can use the common
    > > for() loop method.
    > > Use the fore_each method when you have a generic function, that can be
    > > used with multiple types.

    >
    > Why?
    > I don't see any relation...
    >
    > > Java doesn't have this option, so it's harder to reuse code in Java.

    >
    > Java 5 knows generics, btw...


    Generic what?
    Can you do template coding with Java 5?

    > >> It seems to me the C++ STL algorithm way needs more work. Is that a
    > >> fair comparision?

    > >
    > > No. Since you're comparring apples and oranges. You can use nearly
    > > the same syntax used in Java, and you have more efficient code.

    >
    > More efficient? I doubt that for_each(begin,end,action) boils down to
    > anything else but for(For i=begin; i!=end; ++i) action(*i);


    Have you tried using a Java IDE?
    Every Java IDE I've tried is painfully slow.
    IMHO, why should I bother using Java, if a Java developer can't make a
    decent efficient IDE for the language?
    By evaluating the performance of most Java IDE's, I have to assume
    either there are a lot of bad Java programmers developing IDE's, or
    the language is inefficient in general.
     
    Axter, Jan 17, 2006
    #5
  6. Markus Moll Guest

    Hi

    Axter wrote:

    > Generic what?
    > Can you do template coding with Java 5?


    Depends on what your understanding of "template coding" is.
    You certainly cannot do everything you could do with templates.
    See http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf if you want to
    know more.

    But we're moving off topic...

    >> More efficient? I doubt that for_each(begin,end,action) boils down to
    >> anything else but for(For i=begin; i!=end; ++i) action(*i);

    >
    > Have you tried using a Java IDE?


    Eclipse runs quite well.

    But anyway, it was a misunderstanding. I thought you were comparing for_each
    to a simple for loop, not Java to C++.

    Markus
     
    Markus Moll, Jan 17, 2006
    #6
  7. Guest

    I thought it is better to use for_each than a plain c++ for loop. That
    is why I post my original question.

    >From Effective STL item 43: Prefer algorithm calls to hand-written

    loops.

    Otherwise, there is no need to have the for_each() algorithm, right? we
    can replace all for_each() calls with a plain c++ for loop.

    Thank you.
     
    , Jan 17, 2006
    #7
  8. eiji Guest

    In nearly every second link the guy's in comp.lang.c++ are trying to
    dispose the shared pointers!

    So my question:

    #####some example from boost-hp#####
    ptr_vector<X> pvec;
    std::vector<X*> vec;
    *vec.begin() = new X; // fine, memory leak
    *pvec.begin() = new X; // compile time error
    ( *vec.begin() )->foo(); // call X::foo(), a bit clumsy
    pvec.begin()->foo(); // no indirection needed
    *vec.front() = X(); // overwrite first element
    pvec.front() = X(); // no indirection needed

    #####So this is what I first think of that:
    ptr_vector<X*> pvec; //for generics!!
    std::vector<X*> vec;
    *vec.begin() = new X; // just be sure to delete it, where is the
    problem?
    *pvec.begin() = new X; // now no error!
    ( *vec.begin() )->foo(); // call X::foo(), a bit clumsy, but correct
    pvec.begin()->foo(); // no indirection needed, yes but no generics
    *vec.front() = X(); // overwrite first element
    pvec.front() = X(); // compile time error

    ########
    Is this possible?

    pvec vec
    *vec.begin() = new X;
    ( *vec.begin() )->foo(); // call X::foo(), a bit clumsy, but correct
    *vec.front() = X(); // overwrite first element
    delete *vec.begin(); // delete first element

    does that compile with either
    typedef std::vector<X*> pvec
    or
    typedef ptr_vector<X*> pvec

    Regards,
    Sascha
     
    eiji, Jan 17, 2006
    #8
  9. Luke Meyers Guest

    Markus Moll wrote:
    > >> It seems to me the C++ STL algorithm way needs more work. Is that a
    > >> fair comparision?

    > >
    > > No. Since you're comparring apples and oranges. You can use nearly
    > > the same syntax used in Java, and you have more efficient code.

    >
    > More efficient? I doubt that for_each(begin,end,action) boils down to
    > anything else but for(For i=begin; i!=end; ++i) action(*i);


    I think you might be surprised. Ever heard of loop unrolling, for
    instance?

    Or, better yet, measure it yourself. It's really not hard to get some
    basic perf numbers and answer these things empirically. Or go look up
    the source of your favorite STL implementation.

    Java has all kinds of difficulty competing in terms of performance.
    For example, I recently found a case in which javac generates an extra
    bytecode if certain parentheses are added for clarity.

    Luke
     
    Luke Meyers, Jan 18, 2006
    #9
  10. Guest

    I guess I was trying to find out what are the advantages of using STL
    algorithms over a plain C++ for loop. I did not mean it to be a Java
    Vs C++ discussion.

    In my provided example, it seems to me it requires more code to use STL
    algorithms over a plain c++ loop. And yet, in item 43 of Effective STL
    , it said 'perfer algorithm calls to hand-written loops'. And this is
    what I don't understand...

    Thank you.
     
    , Jan 18, 2006
    #10
  11. Luke Meyers Guest

    wrote:
    > In my provided example, it seems to me it requires more code to use STL
    > algorithms over a plain c++ loop. And yet, in item 43 of Effective STL
    > , it said 'perfer algorithm calls to hand-written loops'. And this is
    > what I don't understand...


    First of all, the size of the code as written does not scale
    predictably with the size of the generated assembly code, or with the
    space or time complexity at runtime. Furthermore, there are often more
    concise ways to provide the behavior than a whole functor object.
    Check out boost::lambda, for one.

    And, of course, not every tool is right for every situation. There are
    times when for_each simply introduces obscurity and doesn't provide an
    appreciable performance gain. Hence, "prefer." Don't twist your code
    into knots trying to always use STL algs for everything -- just see
    that they become well-loved components in your programming toolbox.

    Luke
     
    Luke Meyers, Jan 18, 2006
    #11
  12. Neil Cerutti Guest

    On 2006-01-17,
    <> wrote:
    > I thought it is better to use for_each than a plain c++ for
    > loop. That is why I post my original question.
    >
    >> From Effective STL item 43: Prefer algorithm calls to
    >> hand-written loops.

    >
    > Otherwise, there is no need to have the for_each() algorithm,
    > right? we can replace all for_each() calls with a plain c++ for
    > loop.


    Writing a for loop is often easier than constructing a new
    functor just for one application. If you've already got a nice
    functor lying around, or can adapt an existing one, then for_each
    is fine. Otherwise, I use a for loop.

    for_each is a fairly toothless "algorithm".

    --
    Neil Cerutti
    We're not afraid of challenges. It's like we always say: If you
    want to go out in the rain, be prepared to get burned.
    --Brazillian soccer player
     
    Neil Cerutti, Jan 18, 2006
    #12
  13. Fraser Ross Guest

    > I guess I was trying to find out what are the advantages of using STL
    > algorithms over a plain C++ for loop. I did not mean it to be a Java
    > Vs C++ discussion.
    >
    > In my provided example, it seems to me it requires more code to use

    STL
    > algorithms over a plain c++ loop. And yet, in item 43 of Effective STL
    > , it said 'perfer algorithm calls to hand-written loops'. And this is
    > what I don't understand...
    >
    > Thank you.
    >



    There are probably many advantages that the item has not bothered to
    mention. With a functor the function cannot ordinarily access any other
    element. With a for loop the body may be accessing more than just the
    current element for some reason. There is also opportunity for Jimmying
    the index/counter somehow or to break out early.

    A call to for_each usually is understandable without looking at the
    functor whereas a for loop has a whole load of bits and pieces.

    Fraser.
     
    Fraser Ross, Jan 18, 2006
    #13
  14. David Harmon Guest

    On 18 Jan 2006 08:43:56 -0800 in comp.lang.c++,
    wrote,
    >I guess I was trying to find out what are the advantages of using STL
    >algorithms over a plain C++ for loop. I did not mean it to be a Java
    >Vs C++ discussion.


    Would have better, then, to write the simple loop for comparison in
    C++ using "for" instead of bringing up Java at all. Your post
    looked a lot like the typical Java troll: write something simple in
    Java and a perverse and convoluted version in C++, then compare.

    >In my provided example, it seems to me it requires more code to use STL
    >algorithms over a plain c++ loop. And yet, in item 43 of Effective STL
    >, it said 'perfer algorithm calls to hand-written loops'. And this is
    >what I don't understand...


    You will probably never see much advantage in such a short example
    (And std::for_each<> is probably the least useful!) If "for" fits
    best you should use it. But don't forget about the std algorithms,
    and use them where they fit. The small advantages add up when
    larger numbers of parts start fitting together in the long run.

    It's not fair to write C++ using Java idioms and then complain that
    it's awkward. So for comparison I assume that you don't introduce
    extraneous Rect* pointers as required in Java[*] and that your class
    calculates its own attributes (assigning to a member variable from
    outside the class is naughty.) And I probably screw up the details.
    But your loop might start looking something more like:

    void calculateAreaPerCent(vector<Rect>& rl, double containerArea) {
    std::for_each( rl.begin(), rl.end(),
    std::bind2nd( std::mem_fun(Rect::set_container_area),
    containerArea));
    }

    (I think the need for this is probably bogus from the beginning from
    an OOP point of view, but that goes beyond this thread. areaPercent
    is not an attribute of a Rect and should not be made into one.)

    Modern libraries like boost::lambda greatly reduce the need to write
    those annoying separate helper functions. Something like it will
    eventually make it into some C++ standard.

    ----
    [*] Gratuitous Java bashing merely in return for all the C++ bashing
    done by Java evangelists.
     
    David Harmon, Jan 18, 2006
    #14
  15. Jeff Flinn Guest

    David Harmon wrote:
    >

    ....
    >
    > void calculateAreaPerCent(vector<Rect>& rl, double containerArea) {
    > std::for_each( rl.begin(), rl.end(),
    > std::bind2nd( std::mem_fun(Rect::set_container_area),
    > containerArea));
    > }
    >
    > (I think the need for this is probably bogus from the beginning from
    > an OOP point of view, but that goes beyond this thread. areaPercent
    > is not an attribute of a Rect and should not be made into one.)
    >
    > Modern libraries like boost::lambda greatly reduce the need to write
    > those annoying separate helper functions. Something like it will
    > eventually make it into some C++ standard.


    Indeed:

    void calculateAreaPerCent( vector<Rect>& rl, double containerArea )
    {
    std::for_each
    ( rl.begin()
    , rl.end()
    , std::tr1::bind( &Rect::set_container_area, _1, containerArea )
    );
    }

    Which works for:

    std::vector<Rect>
    std::vector<Rect*>
    std::vector<shared_ptr<Rect> >

    Jeff Flinn
     
    Jeff Flinn, Jan 19, 2006
    #15
  16. Guest

    I thought "_1" is a special expression from Boost lambda library. Is
    that correct?

    So this "std::tr1::bind( &Rect::set_container_area, _1, containerArea )
    " will not work without Boost. Is that true?
     
    , Jan 19, 2006
    #16
  17. Jeff Flinn Guest

    wrote:
    > I thought "_1" is a special expression from Boost lambda library. Is
    > that correct?


    And is also part of std tr1 (technical report 1) bind interface, as well as
    boost's
    bind library as well. Please note that bind library is not the lambda
    library.

    > So this "std::tr1::bind( &Rect::set_container_area, _1, containerArea
    > ) " will not work without Boost. Is that true?


    Not if you have a TR1 library. IIRC, Dinkumware has one, and someone was
    making one available for gcc. Boost bind has some features beyond those that
    were part of the standard submission. For example(untested):

    using namespace boost;

    std::adjacent_find
    ( v.begin()
    , v.end()
    , bind( &C::Name, _1 ) == bind( &C::Name, _2 )
    );

    Jeff Flinn
     
    Jeff Flinn, Jan 19, 2006
    #17
  18. benben Guest

    wrote:
    > I guess I was trying to find out what are the advantages of using STL
    > algorithms over a plain C++ for loop. I did not mean it to be a Java
    > Vs C++ discussion.
    >
    > In my provided example, it seems to me it requires more code to use STL
    > algorithms over a plain c++ loop. And yet, in item 43 of Effective STL
    > , it said 'perfer algorithm calls to hand-written loops'. And this is
    > what I don't understand...
    >
    > Thank you.
    >



    OK. Say you start by doing all the loops in a for statement in C++. At
    first, everything is fine and easy. We are so used to the good old
    for-statement, and we are happy to live with it.

    But then, somewhere down the development we are writting more and more
    for's and we discovered that a lot of them have almost identical
    content. For maintanance's sake, you start to think about refactoring
    out the content to a function. This you did, everything is fine and easy.

    But then, you are writing more and more functions and you discovered
    that a lot of them are almost identical. So you start to add more
    parameters to the functions to make them more flexible. Now you've
    reduced the code base considerably and you are proud of your work.

    Then you discovered that most for-statements you wrote only make a
    function call within it. It is now annoying even to type in the
    conditions for the for-loop and those take up 3 to 4 lines of screen
    space! You start to factor out the for-loops and with a conqueror's
    vision and pride you produced a simple function that handles (almost)
    all the for-loops.

    But then, you just have reinvented the std::for_each family, only tis
    and nothing more.

    Ben
     
    benben, Jan 20, 2006
    #18
    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. Ahmed Moustafa
    Replies:
    0
    Views:
    781
    Ahmed Moustafa
    Nov 15, 2003
  2. Bapaiah Katepalli
    Replies:
    1
    Views:
    1,498
    Mike Treseler
    Jun 23, 2006
  3. Replies:
    6
    Views:
    483
    Jeff Flinn
    Jan 12, 2006
  4. Replies:
    5
    Views:
    602
    benben
    Jan 31, 2006
  5. Isaac Won
    Replies:
    9
    Views:
    383
    Ulrich Eckhardt
    Mar 4, 2013
Loading...

Share This Page