db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "RPost" <rp0...@pacbell.net>
Subject Re: Two poorly optimized functions in SQLParser.java
Date Mon, 27 Dec 2004 19:13:49 GMT
I don't see how the presence or absence of a JIT compiler is relevant.

These extremely nested 'if' statements are part of source code
(SQLParser.java) that is being produced by JavaCC. The source file is then
compiled during build to a class file.

Depending on the JVM being used at run-time there may not even be a JIT
compiler.

The decompiled class file, produced by either Sun's provided 'javac' or
Jikes, also shows a nested if with a separate function call as shown in the
source code.

I am merely suggesting that it would be more efficient if JavaCC produced
'switch' statements for these rather than the nested 'if' statements.

So far, I haven't been able to determine how to modify the sqlgrammar.jj
file to achieve this.

----- Original Message ----- 
From: "Dain Sundstrom" <dsundstrom@gluecode.com>
To: "Derby Development" <derby-dev@db.apache.org>
Sent: Monday, December 27, 2004 10:55 AM
Subject: Re: Two poorly optimized functions in SQLParser.java


You really never know what is going to happen to code once it is passes
through the JIT compiler.  The "if" statement may be converted to a
switch statement.  The "if" statement may be inlined.  The only way to
tell is to time the code in isolation.  Can you write a test case that
tests just the parser code in isolation?  If you can write a isolated
test, don't forget to run the test twice to force the JIT compiler to
kick in and then throw out the first result.  One final thing, a VM
can't really accurately measure a single period shorter then 500 ms.  I
normally do some work in a for loop with a few thousand or million
iterations depending on the thing being measured.  I time the entire
loop, and divid by the number of iterations to get to the time for a
single loop (normally in nanoseconds).

-dain

On Dec 22, 2004, at 2:45 PM, RPost wrote:

> Does anyone have any experience or knowledge about the JavaCC process
> used to produce SQLParser.java?
>
> There are two functions, jj_3R_315() and jj_3R_338(), in
> SQLParser.java that are very poorly optimized.
>
> jj_3R_315 contains around 115 nested IF statements and jj_3R_338
> contains over 200 nested IF statements.
>
> The statement: PreparedStatement pstmt =
> con.prepareStatement("insert into table1 values (?)");
> winds up calling jj_3R_315 three times. For each call the current
> token position is at the "(" and the function executes the entire
> chain of 115 calls:
>
> if (jj_scan_token(208)) {
> jj_scanpos = xsp;
> if (jj_scan_token(209)) {
> jj_scanpos = xsp;
> ... over 100 more nested if statements before finishing.
>
> A stack trace shows that the actual call to jj_3R_315 is about 15
> layers deep:
>
> jj_3_9
> jj_3R_51
> jj_3R_91
> jj_3R_167, which calls 204, 261, 289, 310, 322, 333, 337, 343,
> jj_3R_315
>
> Most of the calling functions do no more than call one function and
> returns its boolean result.
>
> I have not been able to create code that calls the jj_3R_338 function
> but it is similar in structure with a depth of over 200 nested 'if'
> statements. Each 'if' calls the jj_scan_token() function.
>
> The sysinfo for this is:
>
>
>
> D:\cloudscape_derby\test>d:\jdk1.3.1\bin\java -classpath
> .;..\lib\derby.jar;..\lib\derbynet.jar;..\lib\derbytools.jar
> org.apache.derby.tools.sysinfo
>  ------------------ Java Information ------------------
> Java Version: 1.3.1
> Java Vendor: Sun Microsystems Inc.
> Java home: d:\jdk1.3.1\jre
> Java classpath:
> .;..\lib\derby.jar;..\lib\derbynet.jar;..\lib\derbytools.jar
> OS name: Windows 2000
> OS architecture: x86
> OS version: 5.0
> Java user name: Administrator
> Java user home: C:\Documents and Settings\Administrator
> Java user dir: D:\cloudscape_derby\test
> --------- Derby Information --------
> [D:\cloudscape_derby\lib\derby.jar] 10.0.2.1 - (56458)
> [D:\cloudscape_derby\lib\derbynet.jar] 10.0.2.1 - (56458)
> [D:\cloudscape_derby\lib\derbytools.jar] 10.0.2.1 - (56458)
> ------------------------------------------------------
> ----------------- Locale Information -----------------
> ------------------------------------------------------
> Each of the three executions appear to take less than 1ms so I don't
> know how long it is really taking to execute the functions but these
> functions should probably be produced with 'switch' statements like
> many of the other functions in this file are.
>
> Preparation time for the 'insert' statement averages about 250ms.
> Inserting 100 records with:
>
> for (int i = 0; i < 100; i++)
> {
> pstmt.setInt(1, i);
> lStart = System.currentTimeMillis();
> pstmt.execute();
> lEnd = System.currentTimeMillis();
> System.out.println(i + " " + (lEnd - lStart));
> }
> averages about 16ms for each of the 1st 30 records and then about
> 266ms for each of the remaining 70 records.
>
>
>


Mime
View raw message