Testing to which extent method calls affect processig speed

A

Albretch

I wanted to measurably test how much the stack un/rewinding done by function calls taxes processing speed.

... and the winner is ..., well, as we all knew already, using a C-like structure with all members public is consistently fater. It was actually approx. three times as fast as the Java Bean like class with setters and getters methods

My conclusion is, as long as you -internally- use C Structs-like value objects and they don't get exposed by the API itself, you should go for them.

Would you differ? What is it I am missing here?

// - - - - - START OF CODE
// __ Object's state set at creationg time
class JK00{
private int iI;
private int[] iIAr;
private String aS;
private String[] aSAr;
// __
JK00(int iI, int[] iIAr, String aS, String[] aSAr){
this.iI = iI;
this.iIAr = iIAr;
this.aS = aS;
this.aSAr = aSAr;
}
// __
public int getI(){ return(iI); }
public int[] getIAr(){ return(iIAr); }
public String getS(){ return(aS); }
public String[] getSAr(){ return(aSAr); }
}

// - - - - -
// __ Object state resettable for each single member (Java Bean way)
class JK02{
private int iI;
private int[] iIAr;
private String aS;
private String[] aSAr;
// __
JK02(){}
// __
public void setI(int iI){ this.iI = iI; }
public int getI(){ return(iI); }
// __
public void setIAr(int[] iIAr){ this.iIAr = iIAr; }
public int[] getIAr(){ return(iIAr); }
// __
public void setS(String aS){ this.aS = aS; }
public String getS(){ return(aS); }
// __
public void setSAr(String[] aSAr){ this.aSAr = aSAr; }
public String[] getSAr(){ return(aSAr); }
// __
}

// - - - - -
// __ Object state with a bulk set method and single getters
class JK04{
private int iI;
private int[] iIAr;
private String aS;
private String[] aSAr;
// __
JK04(){}
// __
public void setCtxt(int iI, int[] iIAr, String aS, String[] aSAr){
this.iI = iI;
this.iIAr = iIAr;
this.aS = aS;
this.aSAr = aSAr;
}
// __
public int getI(){ return(iI); }
public int[] getIAr(){ return(iIAr); }
public String getS(){ return(aS); }
public String[] getSAr(){ return(aSAr); }
// __
}

// - - - - -

// __ ANSI C struct-like object
class JK06{
public int iI;
public int[] iIAr;
public String aS;
public String[] aSAr;
// __
JK06(){}
}

// - - - - -
import java.io.*;
import java.util.*;
import java.lang.Math.*;

// __
public class TestStructBean06{
static final boolean IsOutFl = false;
// static final boolean IsOutFl = true;
// __
static void setOutputFile(String azOutFlName){
try{
File Fl = new File(azOutFlName);
FileOutputStream OutFlStrm = new FileOutputStream(Fl);
PrintStream PrntStrm = new PrintStream(OutFlStrm);
System.setOut(PrntStrm);
} catch(IOException IOXcptn){ IOXcptn.printStackTrace(); }
}// setOutputFile(String)

// __
public static void main(String[] azArgs){
String azOFlNm ="PrntOut.txt";
if(IsOutFl)setOutputFile(azOFlNm);
long lTm00, lTtlTm;
int iNewObjs, iTms = 4*4096, iTmsTest=16;
JK00 K00;
JK02 K02;
JK04 K04;
JK06 K06;
// __
int iI;
int[] iIAr;
String aS;
String[] aSAr;
// __
String[][] aA2DAr = new String[][]{
{"The","quick","brown","fox","jumped","over","the","lazy","dog"},
{"quick","brown","fox","jumped","over","the","lazy","dog"},
{"brown","fox","jumped","over","the","lazy","dog"},
{"fox","jumped","over","the","lazy","dog"},
{"jumped","over","the","lazy","dog"},
{"over","the","lazy","dog"},
{"the","lazy","dog"},
{"lazy","dog"},
{"dog"}
};
// __
int[][] i2DAr = new int[aA2DAr.length][];
for(int j = 0; (j < aA2DAr.length); ++j){
i2DAr[j] = new int[(j + 1)];
//System.out.println("|" + j + "|" + i2DAr[j].length + "|");
for(int k = 0; (k < i2DAr[j].length); ++k){
//System.out.println("|" + j + "|" + k + "|" + i2DAr[j].length + "|");
i2DAr[j][k] = k;
}// k
}// j
// __
iNewObjs = iTms*(aA2DAr.length*(aA2DAr.length - 1)/2);
// __
long[][] lTests = new long[4][iTmsTest];
for(int iTest = 0; (iTest < iTmsTest); ++iTest){
System.out.println(" iTest: [" + iTest + "," + iTmsTest + ")");
// __ JK00 Objects
lTm00 = System.currentTimeMillis();
for(int i = 0; (i < iTms); ++i){
for(int j = 0; (j < aA2DAr.length); ++j){
for(int k = 0; (k < aA2DAr[j].length); ++k){
K00 = new JK00(k, i2DAr[k], aA2DAr[j][0], aA2DAr[j]);
// __
iI = K00.getI();
iIAr = K00.getIAr();
aS = K00.getS();
aSAr = K00.getSAr();
// __
}// k
}// j
}// i
lTtlTm = (System.currentTimeMillis() - lTm00);
System.out.println(lTtlTm + " milliseconds needed to create " + iNewObjs + " JK00 Objects.");
lTests[0][iTest] = lTtlTm;

// __ JK02 Objects
lTm00 = System.currentTimeMillis();
K02 = new JK02();
for(int i = 0; (i < iTms); ++i){
for(int j = 0; (j < aA2DAr.length); ++j){
for(int k = 0; (k < aA2DAr[j].length); ++k){
// __
K02.setI(k);
K02.setIAr(i2DAr[k]);
K02.setS(aA2DAr[j][0]);
K02.setSAr(aA2DAr[j]);
// __
iI = K02.getI();
iIAr = K02.getIAr();
aS = K02.getS();
aSAr = K02.getSAr();
// __
}// k
}// j
}// i
lTtlTm = (System.currentTimeMillis() - lTm00);
System.out.println(lTtlTm + " milliseconds needed to create " + iNewObjs + " JK02 Objects.");
lTests[1][iTest] = lTtlTm;

// __ JK04 Objects
lTm00 = System.currentTimeMillis();
K04 = new JK04();
for(int i = 0; (i < iTms); ++i){
for(int j = 0; (j < aA2DAr.length); ++j){
for(int k = 0; (k < aA2DAr[j].length); ++k){
K04.setCtxt(k, i2DAr[k], aA2DAr[j][0], aA2DAr[j]);
// __
iI = K04.getI();
iIAr = K04.getIAr();
aS = K04.getS();
aSAr = K04.getSAr();
// __
}// k
}// j
}// i
lTtlTm = (System.currentTimeMillis() - lTm00);
System.out.println(lTtlTm + " milliseconds needed to create " + iNewObjs + " JK04 Objects.");
lTests[2][iTest] = lTtlTm;

// __ JK04 Objects
lTm00 = System.currentTimeMillis();
K06 = new JK06();
for(int i = 0; (i < iTms); ++i){
for(int j = 0; (j < aA2DAr.length); ++j){
for(int k = 0; (k < aA2DAr[j].length); ++k){
// __
K06.iI = k;
K06.iIAr = i2DAr[k];
K06.aS = aA2DAr[j][0];
K06.aSAr = aA2DAr[j];
// __
iI = K06.iI;
iIAr = K06.iIAr;
aS = K06.aS;
aSAr = K06.aSAr;
// __
}// k
}// j
}// i
lTtlTm = (System.currentTimeMillis() - lTm00);
System.out.println(lTtlTm + " milliseconds needed to create " + iNewObjs + " JK06 Objects.");
lTests[3][iTest] = lTtlTm;

}// [0, iTmsTest)
// __
double[][] d2DAr = getStatsAveDev(lTests);
double dMax = Double.MIN_VALUE;
for(int i = 0; (i < d2DAr.length); ++i){
if(dMax < d2DAr[0]){ dMax = d2DAr[0]; }
}

// __
System.out.println();
System.out.println(" Test run " + iTmsTest + " times.");
String[] aSArKNms = new String[]{"JK00", "JK02", "JK04", "JK08"};
System.out.println("- - - - - - - - - - - - - - - - - - - - - - - - - -");
System.out.println("|__class__|__ave. (ms)|__dev. (ms)__|_times faster_|");
for(int i = 0; (i < d2DAr.length); ++i){
//System.out.println("|\t" + aSArKNms + "\t|\t" + d2DAr[0] + "\t|\t" + d2DAr[1] + "\t|\t" + dMax/d2DAr[0] + "\t|");

System.out.printf("| %s |% 9.4f |%9.4f |%9.4f |\n", aSArKNms, d2DAr[0], d2DAr[1], dMax/d2DAr[0]);
System.out.println("- - - - - - - - - - - - - - - - - - - - - - - - - -");

}
}// main

// __
private static double[][] getStatsAveDev(long[][] lVals){
double[][] d2DAr = new double[lVals.length][2];
double dAve;
double dDev;
double dVal;
// __
int iN = lVals.length;
for(int i = 0; (i < iN); ++i){
dAve = .0;
for(int j = 0; (j < lVals.length); ++j){ dAve += lVals[j]; }
d2DAr[0] = dAve/lVals.length;
// __
dDev = .0;
for(int j = 0; (j < lVals.length); ++j){
dVal = (1.*lVals[j] - d2DAr[0]); dDev += dVal*dVal;
}
// __
dDev /= (iN - 1);
d2DAr[1] = Math.sqrt(dDev);
}// i
// __
return(d2DAr);
}
}// TestStructBean06


// - - - - - END OF CODE

Test run 2 times.
- - - - - - - - - - - - - - - - - - - - - - - - - -
|__class__|__ave. (ms)|__dev. (ms)__|_times faster_|
| JK00 | 85.5000 | 12.6557 | 1.1696 |
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK02 | 100.0000 | 0.0000 | 1.0000 |
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK04 | 85.0000 | 4.0825 | 1.1765 |
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK08 | 35.0000 | 4.0825 | 2.8571 |
- - - - - - - - - - - - - - - - - - - - - - - - - -

Test run 2 times.
- - - - - - - - - - - - - - - - - - - - - - - - - -
|__class__|__ave. (ms)|__dev. (ms)__|_times faster_|
| JK00 | 85.0000 | 12.2474 | 1.1765 |
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK02 | 100.0000 | 0.0000 | 1.0000 |
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK04 | 85.5000 | 3.6742 | 1.1696 |
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK08 | 30.0000 | 0.0000 | 3.3333 |
- - - - - - - - - - - - - - - - - - - - - - - - - -


Test run 16 times.
- - - - - - - - - - - - - - - - - - - - - - - - - -
|__class__|__ave. (ms)|__dev. (ms)__|_times faster_|
| JK00 | 71.3750 | 24.3019 | 1.4212 |
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK02 | 101.4375 | 7.5263 | 1.0000 |
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK04 | 80.0625 | 8.1841 | 1.2670 |
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK08 | 35.0625 | 11.7038 | 2.8930 |
- - - - - - - - - - - - - - - - - - - - - - - - - -

Test run 16 times.
- - - - - - - - - - - - - - - - - - - - - - - - - -
|__class__|__ave. (ms)|__dev. (ms)__|_times faster_|
| JK00 | 71.3750 | 24.3019 | 1.4203 |
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK02 | 101.3750 | 7.5664 | 1.0000 |
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK04 | 81.3750 | 7.5664 | 1.2458 |
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK08 | 34.4375 | 11.6324 | 2.9437 |
- - - - - - - - - - - - - - - - - - - - - - - - - -
 
P

P.Hill

Albretch said:
using a C-like structure with all members public is consistently fater. It was actually approx. three times as fast as the Java Bean like class with setters and getters methods
Would you differ? What is it I am missing here?

Yes, I would differ.
This smells like premature optimization to me.

What precentage of the code in an actual app is getter/setter calls?
If it is 1% you have shaved 0.666% off the running of your app.
If it is 10% you have shaved 6% off the running of your app.

I'm still not impressed. You'd better show it it more like 20% percent before
the 13% improvement starts sounding interesting to me.

Having setters and getters is very useful for other reasons.

-Paul
 
A

Albretch

P.Hill said:
Yes, I would differ.
This smells like premature optimization to me.

What precentage of the code in an actual app is getter/setter calls?
If it is 1% you have shaved 0.666% off the running of your app.
If it is 10% you have shaved 6% off the running of your app.

I'm still not impressed. You'd better show it it more like 20% percent before
the 13% improvement starts sounding interesting to me.

Having setters and getters is very useful for other reasons.

-Paul

Doesn't 300% faster sound good enough for you?

Maybe I wasn't clear enough, but I used maximal score proratings.
Meaning, I took the slowest\highest value and divided the rest ones by
all other ones. Look at the code.

So when I say 'times_faster' I mean I divided the slowest value by
the one for this entry
 
M

Matt Humphrey

Albretch said:
"P.Hill" <[email protected]> wrote in message
It was actually approx. three times as fast as the Java Bean like class with
setters and getters methods
Doesn't 300% faster sound good enough for you?

Maybe I wasn't clear enough, but I used maximal score proratings.
Meaning, I took the slowest\highest value and divided the rest ones by
all other ones. Look at the code.

So when I say 'times_faster' I mean I divided the slowest value by
the one for this entry

No one is questioning that you have shown that avoiding an extra layer of
getter / setter methods improves performance. However, any improvement in a
piece of code that comprises only 1% of an application's work is not
necessarily that significant of an improvement, especially when doing so
risks making the design more difficult to build or change. In a sense, your
300% improvement is something like ranking CPU speed based on how fast it
performs no-ops. It presumes that applications do nothing more than get or
set object attributes. Most applications do complex calculations, database
/ storage access, network access, gui control, etc which require only a
small element of attribute / getter setter access. A real sense of the
speed improvement is only meaningful by knowing the frequency getters and
setters are used in an application as a whole.

Cheers,
Matt Humphrey (e-mail address removed) http://www.iviz.com/
 
M

Michael Borgwardt

Albretch said:
... and the winner is ..., well, as we all knew already, using a C-like structure with all members public is consistently fater. It was actually approx. three times as fast as the Java Bean like class with setters and getters methods

Nope, it's not.
My conclusion is, as long as you -internally- use C Structs-like value objects and they don't get exposed by the API itself, you should go for them.

Even if the speed difference really existed, it would still hurt the maintainability
of your code.
Would you differ? What is it I am missing here?

Apart from the other poster's point (that you didn't get):

That code is damn near obfuscated, so I can't even begin to look for
details of the methodology, but your absolute measured times are
too small on a modern machine, so the granularity of the system
clock has a considerable impact.

But the main thing you missed is the existence of the server VM, which
is expecially aggressive about (and successful at) inlining methods,
thereby completely destroying the speed advantages of field access.

This is the result when I run your program on my 2.0 GHz P4 with java -server
using Sun's SDK 1.4.2_04 and making the following podifications:

- fewer repeats, but bigger internal loops:
int iNewObjs, iTms = 256 * 4096, iTmsTest = 4;

- replace unavailable printf() call by string concatenation


Test run 4 times.
- - - - - - - - - - - - - - - - - - - - - - - - - -
|__class__|__ave. (ms)|__dev. (ms)__|_times faster_|
| JK00 | 2763.75 | 276.7554576396522 | 1.0 |
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK02 | 836.5 | 611.654314135035 | 3.3039450089659295 |
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK04 | 558.25 | 88.63925014724948 | 4.9507389162561575 |
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK08 | 533.25 | 32.25290684574028 | 5.182841068917019 |
- - - - - - - - - - - - - - - - - - - - - - - - - -
 
P

P.Hill

Albretch said:
Would you differ? What is it I am missing here?

Let's continue on this original question.
What you are missing is:
The ability to write code such that it tells me what it is doing.
There is little comments of intent and your report of the results
explains nothing. Only your post said 3x better times for set/get vs direct
access. Otherwise what statistics you gathered and what you
want to do with them is defined no where.

Sharing a cryptic chart with 1000s of people without more verbage about the
chart is silly. All it tells me is that there is an "avg.(ms)" of something,
but we can guess it is the runs mentioned above, something called a dev (but is
usually called STD, AKA standard
deviation), and something called "times faster". Apparently
we're supposed to take the time to figure out why the second
line of the table is the 100% value we are comparing to the others.

And what's with all the output to a file, but you don't show us that?

Do you really think code such as
}// [0, iTmsTest)
is useful for somebody looking at it?

Your hungarian notation is sick, just plain sick.
i2DAr vs. aA2DAr etc. is supposed to communicate something?
Even if I decode your hungarian notation all I get is that
we are working with the second array of each. Now why
would that be the most useful information to know?

And these: JK00, JK02, JK04, JK04
have got to be the poorest named classes I've seen in
a long time. If you want to write like that try some assembler
from the early 70's.
return(d2DAr);

FWIW, the parenthesis around a return value are not needed in
either C or Java, despite its idiomatic appearance in
K&R I and K&R II and hence many other books.

Suggestion 1: Learn to communicate to other humans, now that you know
how to communicate to the computer.

Suggestion 2: Figure out where optimization is needed before you
attempt to optimize.

-Paul
 
P

P.Hill

Michael Borgwardt was kind enough to bother with the cryptic code and tried
it on an optimizing VM. I have tiddied up the results and
noted what JK00, JK02, JK04 and JK08 seem to be.
Test run 4 times.
- - - - - - - - - - - - - - - - - - - - - - - - - -
|__class__|__ave. (ms)|__dev. (ms)__ |_times faster_ |
| JK00 | 2763.75 | 276.7554576396522 | 1.0 | c-tor set, 4 getters
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK02 | 836.5 | 611.654314135035 | 3.3039450089659295 | 4 setters, 4 getters
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK04 | 558.25 | 88.63925014724948 | 4.9507389162561575 | 1 4-arg set, 4 getters
- - - - - - - - - - - - - - - - - - - - - - - - - -
| JK08 | 533.25 | 32.25290684574028 | 5.182841068917019 | 4 public members
- - - - - - - - - - - - - - - - - - - - - - - - - -

If Michael ran the same objects as Albretch, which is what he claimed, Michaels
results have the 4 public member variation at 57% overhead as compared with 4
setters and 4 getters. So if time spent calling setters and getters was 10% of
the total of time spent in a program, I'd actually increase by another 5-6% the
runtime of the program!

That's curious results, I wonder if the VM as dropped a few sets/gets just
because the didn't result in anything.

Whatever,
-Paul
 
J

Joona I Palaste

Albretch said:
Maybe I wasn't clear enough, but I used maximal score proratings.
Meaning, I took the slowest\highest value and divided the rest ones by
all other ones. Look at the code.

That's "slowest/highest". "Slowest - frigging / - highest". Just
because Microsoft insists on non-standard typography doesn't mean the
whole world has to.
Nothing against you personally, Albretch. This has been bugging me for
years and I have to let it out occasionally.

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"When a man talks dirty to a woman, that's sexual harassment. When a woman talks
dirty to a man, that's 14.99 per minute + local telephone charges!"
- Ruben Stiller
 
C

Chris Uppal

P.Hill said:
That's curious results, I wonder if the VM as dropped a few sets/gets just
because the didn't result in anything.

I haven't looked at this specific case, but Sun's "server" JVM is /definitely/
capable of destroying simple benchmarks by optimising away code that has no
detectable effect.

-- chris
 
C

Chris Uppal

I said:
I haven't looked at this specific case, but Sun's "server" JVM is
/definitely/ capable of destroying simple benchmarks by optimising away
code that has no detectable effect.

Since posting that, I've realised that it might give the impression that the
"client" JVM is not capable of eliminating dead code. This is not the case,
I've had to re-write (trivial) benchmarks for both VMs to prevent them from
optimising the test code away altogether -- the difference is that the "server"
VM is noticeably better at it.

-- chris
 
A

Ann

How does eliminating code that is not executed change the speed
of the code that is executed? (or maybe I don't understand what
"destroying simple benchmarks" means)
 
A

Albretch

// __
My conclusion is, as long as you -internally- use C Structs-like value objects and they don't
get exposed by the API itself, you should go for them.
AM: I think this is still right

// __
What precentage of the code in an actual app is getter/setter calls? . . .
Suggestion 2: Figure out where optimization is needed before you attempt to optimize.
AM: Many people told me things along this line. You could yourself
easilly see I know this. It is not what I was discussing here.
I am currently doing some simulations as part of a library that
creates classes/objects on the fly and uses them as Value Objects. It
doesn't really matter what they mean, just their 'carrier' usefulness
bringing around data.

// __
Even if the speed difference really existed, it would still hurt the maintainability of your code.
AM: How so? These objects will be used 'internally' they never reach
the API proper

// __
But the main thing you missed is the existence of the server VM, which
is expecially aggressive about (and successful at) inlining methods,
thereby completely destroying the speed advantages of field access.

This is the result when I run your program on my 2.0 GHz P4 with java -server
using Sun's SDK 1.4.2_04 and making the following podifications:
AM: I tried to run the test with the -server option and got:
Error: no `server' JVM at `C:\Program
Files\Java\jre1.5.0\bin\server\jvm.dll'.
java -version
java version "1.5.0-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-rc-b63)
Java HotSpot(TM) Client VM (build 1.5.0-rc-b63, mixed mode, sharing)

// __
I haven't looked at this specific case, but Sun's "server" JVM is /definitely/
capable of destroying simple benchmarks by optimising away code that has no
detectable effect.
AM: Could anyone define to me a little better 'simple benchmarks' and
'code that has no detectable effect'
I did think this NOT to be a 'simple benchmark'.
Would a flattly weighted random selector suffice?

// __
Let's continue on this original question.
What you are missing is:
The ability to write code such that it tells me what it is doing.
There is little comments of intent and your report of the results
explains nothing. Only your post said 3x better times for set/get vs direct
access. Otherwise what statistics you gathered and what you
want to do with them is defined no where.
AM: Mea culpa. I thought it would be easily understandable to java
progs.

// __
Sharing a cryptic chart with 1000s of people without more verbage about the
chart is silly. All it tells me is that there is an "avg.(ms)" of something,
but we can guess it is the runs mentioned above, something called a dev (but is
usually called STD, AKA standard deviation), and something called "times faster". Apparently
we're supposed to take the time to figure out why the second
line of the table is the 100% value we are comparing to the others.
AM: Again, mea culpa. The second 'column' of the table is the average
response time in ms (first one is the table name) I know the JVM does
not give you down to the ms, but enough test would approximate it as
the first deviating value. I wrote 'dev' and I think anyone would
easily understand I mean standard deviation by looking at a piece of
code like:

int iN = lVals.length;
for(int i = 0; (i < iN); ++i){
dAve = .0;
for(int j = 0; (j < lVals.length); ++j){ dAve += lVals[j]; }
d2DAr[0] = dAve/lVals.length;
// __
dDev = .0;
for(int j = 0; (j < lVals.length); ++j){
dVal = (1.*lVals[j] - d2DAr[0]); dDev += dVal*dVal;
}
// __
dDev /= (iN - 1);
d2DAr[1] = Math.sqrt(dDev);
}// i

The third column is the standrad deviation from the previos averaged
value and the Fourth column, 'times_faster', gives you an absolute
number about how many times the average is faster than the slowest
average

// __
And what's with all the output to a file, but you don't show us that?
AM: There is no input to file whatsoever all the response times for
each time are kept in:
long[][] lTests = new long[4][iTmsTest];

// __
Do you really think code such as
}// [0, iTmsTest)
is useful for somebody looking at it?
AM: Actually yu have spotted a real inconsistency of mine ;-) I
usually write it like:

}// iTest [0, iTmsTest)

meaning variable iTest's looping from 0 inklusive to iTmsTest
exclusive ends here

// __
Your hungarian notation is sick, just plain sick.
i2DAr vs. aA2DAr etc. is supposed to communicate something?
Actually it is not exactly a hungarian notation. I learned coding
simulating experiments in FORTRAN and then C (my first/true love) and
I haven't been able to rid certain habits from that time. IT MAKES
THINGS SO F EASIER WHEN YOU ARE DEBUGGING/MENTALLY MAPPING A NUMBER OF
LONG PIECES OF CODE!!! It just reads like prose

For variables:
i2DAr:= two dimensional integer array
a2DAr:= two dimensional array of Strings

when I generate classes on the fly:
3a2id:= class with 3 Strings 2 integers and 1 double
_ab2c:= class with and array of Strings a boolean and two characters

// __
And these: JK00, JK02, JK04, JK04 have got to be the poorest named classes I've seen in a long time.
AM: They were just utility classes they were not supposed to mean
anything. I documented my intent with the heading oneliner
// __ Object's state set at creationg time
class JK00{
.. . .

// __ Object state resettable for each single member (Java Bean way)
class JK02{
.. . .
If you want to write like that try some assembler from the early 70's.
AM: That doesn't really scare me ;-)


// __
return(d2DAr);
FWIW, the parenthesis around a return value are not needed in
either C or Java, despite its idiomatic appearance in
K&R I and K&R II and hence many other books.
AM: They just look nicer to me, like you have input and output
parameters, right?

Now I have always found silly these religious wars about coding
styles. Let me tell you one of the weirdest stories I have had as a
programmer.

As a contractor people dump on me code all the time, that boy! If you
look at it would leave you blind or with cerebral palsy. You would
certainly love me after reading this 'code'. And I am not talking
about its readability here, . . .

In one occasion I was cleaning up other programmers' mess (don't ask,
and yes, some so-called 'programmers' do that and they were paying me
well) it was pieces of 'working they said' perl, vb, java, C code, . .
.. they wanted to recode into java.

I just shut my mouth and silently worked on cleaning up all that
putrid garbage with no documentation whatsoever and repurposing it
(they would 'angrily' tell me that the lead programmer had gone to a
competing company and I was like '. . . and the bad part of the story
is?')

The manager of the project who didn't know much about IT had the
habit of calling methods and classes 'she' and not only that, but
making everyone else do the same!!! I found it so weird/stupid that I
couldn't do it (calling classes and methods 'she'/'her') and I noticed
his not-well-dissimulated anger!?!?
 
P

P.Hill

Albretch said:
AM: How so? These objects will be used 'internally' they never reach
the API proper

What? Your suggesting no one will ever have to debug into your library to find
out what is going on.
AM: I tried to run the test with the -server option and got:

I hope you realized you are responding to two different people who posted responses.
AM: Mea culpa. I thought it would be easily understandable to java
progs.

You wanted to show us some results. Apparently you expect us
to understand most lines of your code in order to do that.
That is no way to attempt to communicate results.
AM: Again, mea culpa. The second 'column' of the table is the average
response time in ms (first one is the table name) I know the JVM does
not give you down to the ms, but enough test would approximate it as
the first deviating value. I wrote 'dev' and I think anyone would
easily understand I mean standard deviation by looking at a piece of
code like:

You're just not interested in communicating to humans are you?
Like I said you expect 1000s of people to wade through your
code and then look at your charts. You expect way to much.
AM: Actually yu have spotted a real inconsistency of mine ;-) I
usually write it like:

}// iTest [0, iTmsTest)

And you posting your un-cleaned up code with such cryptic stuff just shows
you haven't a clue how to attempt to communicate with the most number of
people.
Actually it is not exactly a hungarian notation.

I could tell.

I learned coding
simulating experiments in FORTRAN and then C (my first/true love) and
I haven't been able to rid certain habits from that time. IT MAKES
THINGS SO F EASIER WHEN YOU ARE DEBUGGING/MENTALLY MAPPING A NUMBER OF
LONG PIECES OF CODE!!! It just reads like prose

For variables:
i2DAr:= two dimensional integer array
a2DAr:= two dimensional array of Strings

Were you planning on people just guessing your non-standard convention?
Again, no consideration for the reader.
AM: They were just utility classes they were not supposed to mean
anything. I documented my intent with the heading oneliner
// __ Object's state set at creationg time

But you posted the code for God's sake, you wanted us to read it!
Make a non-automated version with helpful names next time.

later,
-Paul
 
A

Andrew Thompson

How does eliminating code that is not executed change the speed
of the code that is executed?

Chris did not say 'not executed' he said
'no detectable effect'.
That is an important distinction.

You may be testing a method that returns a value,
that code *is* executed. But if you do that a
million times, and each time immediately discard the
result (a benchmark is only really interested in the time
lapse between the start and end of the million calls),
an omptimizer may work out that it is faster (with
'same' end result) to skip the million calls completely.
 
M

Michael Borgwardt

Albretch said:
AM: I tried to run the test with the -server option and got:
Error: no `server' JVM at `C:\Program
Files\Java\jre1.5.0\bin\server\jvm.dll'.

You have to call the java executable for the JDK, not the JRE.

Pretty idiotic decision from Sun to hide their best optimizing
JVM that way.
 
C

Chris Uppal

Ann said:
that the "client" JVM is not capable of eliminating dead code. This is
[...]
How does eliminating code that is not executed change the speed
of the code that is executed? (or maybe I don't understand what
"destroying simple benchmarks" means)

I should have said "code that has no detectable effects", rather than "dead
code" (which does indeed mean code that is not executed). Careless mistake on
my part, sorry.

But I /did/ get it right in the earlier post ;-)

-- chris
 
M

Michael Borgwardt

Albretch said:
Actually it is not exactly a hungarian notation. I learned coding
simulating experiments in FORTRAN and then C (my first/true love) and
I haven't been able to rid certain habits from that time. IT MAKES
THINGS SO F EASIER WHEN YOU ARE DEBUGGING/MENTALLY MAPPING A NUMBER OF
LONG PIECES OF CODE!!! It just reads like prose

To me, it's just unintelligible gibberish.
For variables:
i2DAr:= two dimensional integer array
a2DAr:= two dimensional array of Strings

when I generate classes on the fly:
3a2id:= class with 3 Strings 2 integers and 1 double
_ab2c:= class with and array of Strings a boolean and two characters

Even if you have internalized this and the usual problems of hungarian
notation aside: It's completely worthless for understanding what the
code DOES!

Technical details like these aren't what variable or class names must convey,
they're already present in the declarations. Lack of this information is NOT
what makes code difficult to understand.

To be useful at all, names must, absolutely MUST, convey information about
the *function* of the variable or class. Everything else is obfuscation.

You have posted a good example of horribly obfuscated, nearly impossible to
understand code. Duplicating the type information in the names does not help
in understanding it at all. What it needs are "talking" names like
StructData, GetSetData ConstructorGetData instead of JK00, JK02, JK04
and classNames, averageTimes, timeDeviation instead of aSArKNms, d2DAr
 
A

Albretch

P.Hill said:
Make a non-automated version with helpful names next time.

later,
-Paul

The code I posted I quickly scratched manually.

1._ What would you consider 'helpful names'? Isn't documentation
enough?
Please, could you send to me -good- links about the 'cultural/social
aspects' of code?

To me, anyone that comes with a history of C-like 'itoa' routines
would easily understand my code. But I think you are very close to
convince me I should change my habits at once if I plan to post
libraries for the general public out there.

2._ Is there such thing as a Java code beautifier?

3._ I have taken the time to read source code libraries and they are
nicely javadoc'ed, but sometimes I find things I wouldn't consider so
clearly coded. I have heard the Linux Kernel source code is
excellently documented, but I would like to read some real Java code
out there that has been well documented.

See you
AM
 

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,754
Messages
2,569,527
Members
44,998
Latest member
MarissaEub

Latest Threads

Top