nit-pick optimization for findColumn() - Mailing list pgsql-jdbc
From | Peter Speck |
---|---|
Subject | nit-pick optimization for findColumn() |
Date | |
Msg-id | 4CDDFBBC-9EB3-11D7-BE5A-0030654BB35C@ruc.dk Whole thread Raw |
Responses |
Re: nit-pick optimization for findColumn()
|
List | pgsql-jdbc |
Hi, (I have not submitted this to the patch list, as I do not know if I should do that, or if there is a jdbc maintainer which gatekeeps patches) A very small optimization, but anyway. findColumn() uses String.equalsIgnoreCase() which is slow. I've made a simple optimization which first tries a simple ASCII ignorecase loop, and falls back to equalsIgnoreCase if the simple loop can't find the column (should only happend if you have non-ascii characters in the name). Using findColumn from 7.3.3: Time for test: 1446 msecs. Time for TEST: 2382 msecs. Time for TeSt: 1975 msecs. Time for héllo: 6342 msecs. Time for HÉLLO: 7511 msecs. Time for col_1: 556 msecs. Time for col_2: 1488 msecs. // long common prefix Time for col_3: 2421 msecs. Time for col_4: 3286 msecs. Time for col_5: 4227 msecs. Using optimized findColumn: Time for test: 767 msecs. Time for TEST: 777 msecs. Time for TeSt: 777 msecs. Time for héllo: 1443 msecs. Time for HÉLLO: 8626 msecs. Time for col_1: 613 msecs. Time for col_2: 1109 msecs. Time for col_3: 1651 msecs. Time for col_4: 2087 msecs. Time for col_5: 2622 msecs. (java 1.4.1, PowerPC, Mac OS X 10.2.6) @@@@@@@@@@@@@ DIFF FOR CVS HEAD @@@@@@@@@@@@@@ Index: pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/ AbstractJdbc1ResultSet.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/ jdbc1/AbstractJdbc1ResultSet.java,v retrieving revision 1.12 diff -u -d -b -w -r1.12 AbstractJdbc1ResultSet.java --- pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/ AbstractJdbc1ResultSet.java 3 May 2003 20:40:45 -0000 1.12 +++ pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/ AbstractJdbc1ResultSet.java 14 Jun 2003 21:50:27 -0000 @@ -607,6 +607,25 @@ int i; final int flen = fields.length; + final int cnlen = columnName.length(); + for (i = 0 ; i < flen; ++i) { + String fieldName = fields[i].getName(); + if (fieldName.length() != cnlen) + continue; + int j = 0; + while (true) { + int ch1 = columnName.charAt(j); + int ch2 = fieldName.charAt(j); + if (ch1 >= 'A' && ch1 <= 'Z') + ch1 += 'a' - 'A'; + if (ch2 >= 'A' && ch2 <= 'Z') + ch2 += 'a' - 'A'; + if (ch1 != ch2) + break; + if (++j >= cnlen) + return i + 1; + } + } for (i = 0 ; i < flen; ++i) if (fields[i].getName().equalsIgnoreCase(columnName)) return (i + 1); @@@@@@@@@@@@@ DIFF FOR 7.3.3 @@@@@@@@@@@@@@ --- org/postgresql/jdbc1/orig-AbstractJdbc1ResultSet.java Tue Jan 14 10:15:35 2003 +++ org/postgresql/jdbc1/AbstractJdbc1ResultSet.java Sat Jun 14 23:24:09 2003 @@ -522,6 +522,25 @@ int i; final int flen = fields.length; + final int cnlen = columnName.length(); + for (i = 0 ; i < flen; ++i) { + String fieldName = fields[i].getName(); + if (fieldName.length() != cnlen) + continue; + int j = 0; + while (true) { + int ch1 = columnName.charAt(j); + int ch2 = fieldName.charAt(j); + if (ch1 >= 'A' && ch1 <= 'Z') + ch1 += 'a' - 'A'; + if (ch2 >= 'A' && ch2 <= 'Z') + ch2 += 'a' - 'A'; + if (ch1 != ch2) + break; + if (++j >= cnlen) + return i + 1; + } + } for (i = 0 ; i < flen; ++i) if (fields[i].getName().equalsIgnoreCase(columnName)) return (i + 1); // TEST APPLICATION. import java.sql.*; public class test { // must pass connection URL as first argument. public static void main(String[] argv) { try { DriverManager.registerDriver(new org.postgresql.Driver()); Connection conn = DriverManager.getConnection(argv[0]); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery( "SELECT\n" + " 1 as col_1,\n" + " 2 as col_2,\n" + " 3 as col_3,\n" + " 4 as col_4,\n" + " 5 as col_5,\n" + " 6 as col_6,\n" + " 7 as col_7,\n" + " 8 as \"héllo\",\n" + // with accent: e´ " 9 as warm_up,\n" + " 0 as test\n"); time(rs, 9, "warm_up"); time(rs, 9, "warm_up"); time(rs, 10, "test"); time(rs, 10, "TEST"); time(rs, 10, "TeSt"); time(rs, 8, "héllo"); time(rs, 8, "HÉLLO"); time(rs, 1, "col_1"); time(rs, 2, "col_2"); time(rs, 3, "col_3"); time(rs, 4, "col_4"); time(rs, 5, "col_5"); System.err.println(sb.toString()); } catch (Exception ex) { ex.printStackTrace(); } } static StringBuffer sb = new StringBuffer(); static void time(ResultSet rs, int wanted, String colName) throws SQLException { if (rs.findColumn(colName) != wanted) throw new SQLException("Fails for " + colName); int num = 1000000; long st0 = System.currentTimeMillis(); for (int i = num; i > 0; i--) rs.findColumn(colName); long st1 = System.currentTimeMillis(); sb.append(" Time for " + colName + ": " + (st1 - st0) + " msecs.\n"); } } // END OF FILE ---- - Peter Speck "The difference between theory and practice is small in theory and large in practice..."
pgsql-jdbc by date: