Newsgroups: comp.lang.java.programmer,comp.lang.java,comp.lang.functional,comp.lang.misc,comp.lang.smalltalk,comp.lang.c,comp.lang.c++
Path: cantaloupe.srv.cs.cmu.edu!rochester!udel-eecis!news.mathworks.com!newsfeed.internetmci.com!uwm.edu!fnnews.fnal.gov!cbgw1.att.com!nntphub.cb.lucent.com!newshub.netnews.att.com!ulysses!allegra!akalice!ark
From: ark@research.att.com (Andrew Koenig)
Subject: Re: Three languages: A performance comparison
Message-ID: <DvD39L.F8L@research.att.com>
Organization: AT&T Research, Murray Hill NJ
References: <4te7rg$287o@piglet.cc.uic.edu>
Date: Tue, 30 Jul 1996 15:05:44 GMT
Lines: 105
Xref: glinda.oz.cs.cmu.edu comp.lang.java.programmer:2604 comp.lang.java:72817 comp.lang.functional:7706 comp.lang.misc:26417 comp.lang.smalltalk:41641 comp.lang.c:199170 comp.lang.c++:203249

In article <4te7rg$287o@piglet.cc.uic.edu> dhanle2@icarus.cc.uic.edu (David James Hanley) writes:

> 	I've been following the discussions in the comp.lang.* groups
> convcerning performance with a lot of interest.  And, although a lot
> of people voiced thier opinions about the matter, very few had hard 
> facts to back them up.  So I decided to do a little benchmark.  

Excellent idea.

> 	The program caries out some basic arithmetic operations
> with a datatype that manipulates arbitrarily large integers.
> I used this example because it is of interest to me, for a project
> that I am working on.  Different benchmarks will of course yeild 
> different results.

Yes indeed.

Looking at the sample programs you posted, two things seemed clear
to me:

	1. The C++ version was a translation of the ML version,
	   hence probably not idiomatically suited to C++;

	2. The C++ version uses new and delete extensively for
	   single elements, which can be slow on many implementations.

So I decided to translate the ML algorithm into C++ in what I think
of as a more idiomatic way.  The ML version uses lists, essentially
iterating from front to back (although the iteration is expressed
recusrively), so I decided to use a similar sequential data structure
for the C++ version.  I picked the STL vector<int> class because of
a hunch that it would perform well.  I did not measure alternative
data structures, nor did I try to tweak the C++ program after
writing it to see if it would work better.

I didn't try to rewrite the Java version because I don't know
Java well enough to have any confidence in the results.

> Finally, here are the results:
> (in seconds)
>                    Taking large       summing
>                    powers of 2        large numbers.
> ----------------------------------------------------
> 	java :       15.32             3.89
>         C++  :       22.79            51.3
>         SML  :        7.0              2.2

I don't know what large numbers you summed, so I could not replicate
that column.  However, here are my results for the lower left corner,
run on a Sparcstation 2:

			Taking large
			powers of 2
	--------------------------------
	C++ :		1.4	(compiler optimization off)
	C++ :		1.1	(compiler optimization on)
	SML :		9.0

Here is the C++ code.  I imagine that it could be made faster by tweaking,
but I think the overall structure is not hard to understand.  Note also
that memory management in this version is implicit, as it is in the ML version:

vector<int>&
operator+=(vector<int>& v, const vector<int>& w)
{
	// Ensure that v is at least as large as w
	while (v.size() < w.size())
		v.push_back(0);

	register vector<int>::iterator vp = v.begin();
	register vector<int>::iterator ve = v.end();
	register vector<int>::const_iterator wp = w.begin();
	register vector<int>::const_iterator we = w.end();
	register int carry = 0;

	// Add the elements of w into v
	while (wp != we) {
		register long result = *vp;
		result += *wp++;
		result += carry;
		*vp++ = result & 0xffff;
		carry = (result & ~0xffffL) >> 16;
	}

	// Propagate carries to the end of v, if needed
	while (carry && vp != ve) {
		register long result = *vp;
		result += carry;
		*vp++ = result & 0xffff;
		carry = (result & ~0xffffL) >> 16;
	}

	// The final carry might extend v
	if (carry)
		v.push_back(carry);

	return v;
}

-- 
				--Andrew Koenig
				  ark@research.att.com
-- 
				--Andrew Koenig
				  ark@research.att.com
