Iterators in Java and C++

  • Thread starter Erik Wikström
  • Start date
E

Erik Wikström

This is a little bit off topic but I hop you'll forgive me.

A few days ago some expressed the opinion (in a post I can't find, but
it was probably in one of Razii's threads) that Java's iterators were
better than C++ iterators, or at least that the Java iterator concept
was better (or something to that effect). I would be interested to hear
about why whoever wrote it feels that way.
 
R

Razii

A few days ago some expressed the opinion (in a post I can't find, but
it was probably in one of Razii's threads) that Java's iterators were
better than C++ iterators, or at least that the Java iterator concept
was better (or something to that effect). I would be interested to hear
about why whoever wrote it feels that way.

For fun, I sent the blog page

(http://razi2.blogspot.com/2008/04/why-is-c-slower-than-java.html )

to the author of
http://bruscy.multicon.pl/pages/przemek/java_not_really_faster_than_cpp.html

his email response was:

-- quote--
see explanation to hash.cpp and hash2.cpp on my webpage.
If you use standard library as defined in 1998, you can't make the C++
faster. You either have to use original SGI STL map or unordered_map
from C++ 0x . (Or any hashmap from less standard sources like Boost).
With any of these solutions, C++ beats Java hands down.

There are other performance problems in the code, like this line:
std::string input( buffer.str() );
which needlessly copies the whole 40MB for the second time, but the
performance impact of that is insignificant in comparison to the
impact of using tree based map.
-- end quote ---

I am not sure what that really means but I am still waiting for C++
version that is faster and would compile on GCC.
 
R

Razii

Onn Thu, 03 Apr 2008 19:12:27 GMT, Erik Wikström..
A few days ago some expressed the opinion (in a post I can't find, but
it was probably in one of Razii's threads) that Java's iterators were
better than C++ iterators, or at least that the Java iterator concept
was better (or something to that effect). I would be interested to hear
about why whoever wrote it feels that way.

For fun, I sent the blog page

(http://razi2.blogspot.com/2008/04/why-is-c-slower-than-java.html )

to the author of
http://bruscy.multicon.pl/pages/przemek/java_not_really_faster_than_cpp.html

his email response was:

-- quote--
see explanation to hash.cpp and hash2.cpp on my webpage.
If you use standard library as defined in 1998, you can't make the C++
faster. You either have to use original SGI STL map or unordered_map
from C++ 0x . (Or any hashmap from less standard sources like Boost).
With any of these solutions, C++ beats Java hands down.

There are other performance problems in the code, like this line:
std::string input( buffer.str() );
which needlessly copies the whole 40MB for the second time, but the
performance impact of that is insignificant in comparison to the
impact of using tree based map.
-- end quote ---

I am not sure what that really means but I am still waiting for C++
version that is faster and would compile on GCC..
 
J

James Kanze

This is a little bit off topic but I hop you'll forgive me.
A few days ago some expressed the opinion (in a post I can't
find, but it was probably in one of Razii's threads) that
Java's iterators were better than C++ iterators, or at least
that the Java iterator concept was better (or something to
that effect). I would be interested to hear about why whoever
wrote it feels that way.

That was me, and the reason is simply: you don't need two of
them. Try chaining functions which use iterators, for example.
Or writing a filtering iterator.

Not that Java's iterators are perfect, either. The merge access
and incrementing---as did the USL iterators. By the time Java
was being developed, we'd already established that this wasn't a
good idea, so it's hard to understand why they did it.
 
E

Erik Wikström

For fun, I sent the blog page

(http://razi2.blogspot.com/2008/04/why-is-c-slower-than-java.html )

to the author of
http://bruscy.multicon.pl/pages/przemek/java_not_really_faster_than_cpp.html

his email response was:

-- quote--
see explanation to hash.cpp and hash2.cpp on my webpage.
If you use standard library as defined in 1998, you can't make the C++
faster. You either have to use original SGI STL map or unordered_map
from C++ 0x . (Or any hashmap from less standard sources like Boost).
With any of these solutions, C++ beats Java hands down.

There are other performance problems in the code, like this line:
std::string input( buffer.str() );
which needlessly copies the whole 40MB for the second time, but the
performance impact of that is insignificant in comparison to the
impact of using tree based map.
-- end quote ---

I am not sure what that really means but I am still waiting for C++
version that is faster and would compile on GCC.

Relevance?
 
E

Erik Wikström


Yes, thanks.

James, can you explain what you meant by "... for most everyday jobs
like this, in fact, the Java collections library (and especially the
concept of iterators in Java) is far superior to the STL."?

While it was some time ago since I last used Java (before generics) I've
always liked the way the STL iterators, it is a quite simple concept but
still very powerful. To my knowledge there is not easy way to perform
operations on a subset of a container using Java's iterators.
 
R

Razii

Not that Java's iterators are perfect, either. The merge access
and incrementing---as did the USL iterators. By the time Java
was being developed, we'd already established that this wasn't a
good idea, so it's hard to understand why they did it.


I am not sure what you mean but with with 1.5, the syntax changed from

for(Iterator lineup = list.iterator() ; lineup.hasNext() ; ) {
Object thatThing = lineup.next();
myMonster.eat(thatThing);
}

to

for(Object thatThing : list) {
myMonster.eat(thatThing);
}
 
L

Lloyd Bonafide

This is stupid. This is like saying that apples are better than
oranges. Some people like apples more than oranges, other people like
oranges more than apples. There is no quantifiable way to compare
apples and oranges on some nebulous,

Right, there is no quantifiable way to compare the taste of apples and
oranges, nor is there a way to convince someone that one is better than
another. With programming constructs or paradigms, however, there are
often tradeoffs in choosing one over another, and reasons for choosing
one over another can be concrete.
 
J

James Kanze

On 2008-04-03 21:38, (e-mail address removed) wrote:

[...]
James, can you explain what you meant by "... for most everyday jobs
like this, in fact, the Java collections library (and especially the
concept of iterators in Java) is far superior to the STL."?
While it was some time ago since I last used Java (before generics) I've
always liked the way the STL iterators, it is a quite simple concept but
still very powerful. To my knowledge there is not easy way to perform
operations on a subset of a container using Java's iterators.

It's easier with Java's iterators than with those of C++. Try
it sometime: call std::transform with some function which should
only be applied to every third element. In Java, you simply
create a filtering iterator (using an anonymous class, if you
wish). In C++, you use boost::filtering_iterator, of course,
it's still more awkward (since you need to create two of them),
and from a purely STL point of view, you should take a look at
the hoops boost::filtering_iterator has to jump through.

Of course, the real problem comes when you want to call a
function to operate on a subset determined by another function.
In Java, that would simply be f( g( collection ), operation ),
where g( collection ) returns a filtering iterator, and f takes
an iterator (any iterator of the correct type), and the
functional operation object. In C++, g must return a pair of
iterators, and you need to store them somewhere, and then call
f() in a separate statement.

Projection and filtering iterators, and function chaining, are
some of the most fundamental concepts, which I used to use
everywhere, in pre-STL days.

The iterator pattern in the GoF was established and standard
practice as early as 1990. Neither Java nor the STL have the
excuse of not knowing the flaws in their iterator idiom by the
time they were developing them. In the case of Java, they
adopted existing practice (e.g. the USL library) known to be
somewhat flawed (next and accessing the element should be two
separate operations); in the case of the STL, the authors
decided to ignore all existing practice, and invented something
far less usable.

(There are few special cases where the two iterator model is
useful. It works well for tokenizing an input stream, for
example. The problem with this is that every time I've wanted
to tokenize an input stream, I've either had input
iterators---which don't allow establishing a sub-range using a
previously saved iterator---or a random access container, in
which case, I could just as easily use indexes, rather than
iterators. In fact, my ParserSource class is modeled more on
C++'s other iterators, streambuf, than it is on STL iterators.
But it really could be just a GoF iterator as well.)
 
J

James Kanze

You have Iterators only when you have containers, like map or
vector :)

Since when? C++ has istream_iterator in the standard, and Boost
has a lot of iterators which don't depend on an underlying
container. And you can easily do the same thing in Java---much
more easily, in fact. (The fact that they are so easy to
implement may account for why no one felt it necessary to
provide them as standard, or as part of a widely used library.)
 
J

James Kanze

I am not sure what you mean but with with 1.5, the syntax
changed from
for(Iterator lineup = list.iterator() ; lineup.hasNext() ; ) {
Object thatThing = lineup.next();

And that's the problem. You should be able to access the object
without advancing the iterator. Most logically, advancing the
iterator should be the third part of the if.

The standard "pattern" is:

for ( Iterator iter( someInitializationArguments ) ;
! iter.isDone() ;
iter.next() ) {
doSomethingWith( iter.element() ) ;
}

In a well written iterator, doSomethingWith should encompass
deleting the element from the container, if the iterator is
based on a container. (IIRC, Java supports this; C++ definitely
doesn't.)
myMonster.eat(thatThing);
}

for(Object thatThing : list) {
myMonster.eat(thatThing);
}

Interesting. But isn't it just a cosmetic fix? Suppose that my
doSomethingWith, above, was actually to remove the element from
the underlying container, g.e.:

for ( Iterator i = list.iterator() ; list.hasNext() ; ) {
Object o = iter.next() ;
if ( condition( o ) ) {
iter.remove() ;
}
}

Try writing a filtering iterator in Java which supports that,
and you'll see why merging advance and access is a bad idea.
(Of course, from a design point of view, it's very ugly.
Separation of concerns should be an important guiding
principle.)
 
J

James Kanze

This is stupid. This is like saying that apples are better
than oranges.

No. You're not comparing things in an absolute. If you call
something an "iterator", it is because it fulfills a specific
purpose. Implicit in the statement is that "Java iterators are
better iterators than C++ iterators". Sort of like "oranges are
a better source of vitamin C than apples".
 
M

Markus Moll

Hi
If the problem is that "You should be able to access the object
without advancing the iterator", where am I calling next in this
syntax.
Easy...

int[] nums = { 1, 2, 3, 4, 5, 6 };

for(int n : nums) {
^^^^^^^^^^^^

Here...
System.out.println(n);
}

Or

List list = getList();

for (Object element : list) {
^^^^^^^^^^^^^^^^^^^^^
.... and here.
out.println(element);

// Do something else with this element
}

Markus
 
L

Lloyd Bonafide

James Kanze writes:

Except that there is no common denominator between Java and C++
iterators that can be used as a measuring stick. A better analogy
would be saying that because both apples and oranges are fruits, one
of them is a better fruit than the other.

Totally meaningless.

Both Java and C++ implement iterators over containters, and I think Java
containers are better implemented because...

The because part is what Erik was asking James about.
 
O

Obnoxious User

You have Iterators only when you have containers, like map or vector :)

No, you don't. I even use custom iterators for a lot more than
simple containers.
 
L

Lloyd Bonafide

Before you can make that argument, you need to define what "better"
means. And, what "better" might mean to you, in this context, may not
necessarily mean the same thing to someone else, who uses a different
definition of "better".

Maybe it will help you to preface each post, in your mind, with "in my
opinion". James' opinion is that Java's iterator implementation is
superior to C++, and Erik wants to know why he thinks that. No need to
get your shorts in a wad.

<remainder of cowboy programmer bullshit elided>
 
M

Mirek Fidler

What the Java fan club fails to comprehend is that each iteration, in Java,
involves two virtual function calls: hasNext() and next(), while equivalent
C++ code is likely to involve more than a pair of CPU instructions:
increment and comparison, since the C++ generated code is likely to inline

What makes you think that "hasNext" and "next", if implemented in C++,
would not be expressed by "a pair of CPU instructions" - compare and
increment?
and keep both iterators in registers (most C++ STL iterators usually get
optimized into nothing more than glorified pointers).

As could be Java style iterators implemented in C++. Just consider

template <class T>
struct Iter {
T::iterator ptr;
T::iterator end;

bool hasNext() const { return ptr != end; }
void next() { ptr++; }
};

Your arguments are completely moot.
Meanwhile, since all Java methods are virtual, unless explicitly specified
otherwise; and I'm rather skeptical that even modern Java VMs will be able
to optimize away the required virtual function calls, one for each method:
hasNext(), and next(), on each iteration.

What that has to do with iterator concept?

Mirek
 

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,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top