Testing to which extent method calls affect processig speed

Discussion in 'Java' started by Albretch, Sep 8, 2004.

  1. Albretch

    Albretch Guest

    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 |
    - - - - - - - - - - - - - - - - - - - - - - - - - -
     
    Albretch, Sep 8, 2004
    #1
    1. Advertising

  2. Albretch

    P.Hill Guest

    Albretch wrote:
    >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
     
    P.Hill, Sep 9, 2004
    #2
    1. Advertising

  3. Albretch

    Albretch Guest

    "P.Hill" <> wrote in message news:<chop5g$roj$>...
    > Albretch wrote:
    > >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


    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
     
    Albretch, Sep 9, 2004
    #3
  4. "Albretch" <> wrote in message
    news:...
    > "P.Hill" <> wrote in message

    news:<chop5g$roj$>...
    > > Albretch wrote:
    > > >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

    >
    > 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 http://www.iviz.com/
     
    Matt Humphrey, Sep 9, 2004
    #4
  5. Albretch wrote:

    > ... 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 |
    - - - - - - - - - - - - - - - - - - - - - - - - - -
     
    Michael Borgwardt, Sep 9, 2004
    #5
  6. Albretch

    P.Hill Guest

    Albretch wrote:
    > 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.Hill, Sep 9, 2004
    #6
  7. Albretch

    P.Hill Guest

    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
     
    P.Hill, Sep 9, 2004
    #7
  8. Albretch <> scribbled the following:
    > 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 () ------------- 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
     
    Joona I Palaste, Sep 9, 2004
    #8
  9. Albretch

    Chris Uppal Guest

    P.Hill wrote:

    > 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
     
    Chris Uppal, Sep 9, 2004
    #9
  10. Albretch

    Chris Uppal Guest

    I wrote:

    > 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
     
    Chris Uppal, Sep 10, 2004
    #10
  11. Albretch

    Ann Guest

    "Chris Uppal" <-THIS.org> wrote in message
    news:...
    > I wrote:
    >
    > > 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.


    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)

    >
    > 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
    >
    >
    >
     
    Ann, Sep 10, 2004
    #11
  12. Albretch

    Albretch Guest

    // __
    > 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!?!?
     
    Albretch, Sep 10, 2004
    #12
  13. Albretch

    P.Hill Guest

    Albretch wrote:

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


    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.

    >> 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:


    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.

    >>Your hungarian notation is sick, just plain sick.

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

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


    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
     
    P.Hill, Sep 10, 2004
    #13
  14. On Fri, 10 Sep 2004 00:05:32 GMT, Ann wrote:

    > "Chris Uppal" <-THIS.org> wrote in message


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

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

    --
    Andrew Thompson
    http://www.PhySci.org/ Open-source software suite
    http://www.PhySci.org/codes/ Web & IT Help
    http://www.1point1C.org/ Science & Technology
     
    Andrew Thompson, Sep 10, 2004
    #14
  15. Albretch wrote:
    > 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.
     
    Michael Borgwardt, Sep 10, 2004
    #15
  16. Albretch

    Chris Uppal Guest

    Ann wrote:

    > > 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
     
    Chris Uppal, Sep 10, 2004
    #16
  17. Albretch wrote:
    > 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
     
    Michael Borgwardt, Sep 10, 2004
    #17
  18. Albretch

    Albretch Guest

    "P.Hill" <> wrote in message news:<chr8bn$s0k$>...
    .. . .
    > 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
     
    Albretch, Sep 10, 2004
    #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. Sidney Cadot

    Extent of the "as-if" rule

    Sidney Cadot, Jan 19, 2004, in forum: C Programming
    Replies:
    145
    Views:
    2,179
  2. Replies:
    0
    Views:
    897
  3. robert
    Replies:
    0
    Views:
    281
    robert
    Dec 10, 2006
  4. Matt White
    Replies:
    8
    Views:
    342
    Neredbojias
    Aug 13, 2007
  5. Lew
    Replies:
    63
    Views:
    1,424
    Arne Vajhøj
    May 27, 2010
Loading...

Share This Page