STL algorithm VS Java loop

A

Allerdyce.John

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.
 
A

Axter

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.
 
M

Markus Moll

Hi
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...
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
 
A

Axter

Markus said:
Hi


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


Java 5 knows generics, btw...

Generic what?
Can you do template coding with Java 5?
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.
 
M

Markus Moll

Hi
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...
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
 
A

Allerdyce.John

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.
 
E

eiji

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
 
L

Luke Meyers

Markus said:
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
 
A

Allerdyce.John

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.
 
L

Luke Meyers

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
 
N

Neil Cerutti

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


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".
 
F

Fraser Ross

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.
 
D

David Harmon

On 18 Jan 2006 08:43:56 -0800 in comp.lang.c++,
(e-mail address removed) 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.
 
J

Jeff Flinn

David said:
....

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
 
A

Allerdyce.John

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?
 
J

Jeff Flinn

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
 
B

benben

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top