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.





Reply via email to