Fast BigDecimal

Поиск
Список
Период
Сортировка
Искать
От
Heikki Linnakangas
Тема
Fast BigDecimal
Дата
Msg-id
49E72C90.9010903@enterprisedb.com
Список
Дерево обсуждения
Re: Unit tests and ordering "John Lister" <john.lister-ps@kickstone.com>
Here's another patch I put together while trying to improve performance 
for the customer that bumped into the repeated Describe thing yesterday. 
It speeds up ResultSet.getBigDecimal() with the same fastpath 
implementation we have for getInt and getLong.

I'm testing this with a test program that reads 10000 rows from a table 
with 100 numeric columns, calling getBigDecimal() on each column. This 
patch cuts the execution time roughly in half, from 2.4s to 1.2s.

-- 
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com
Index: org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
===================================================================
RCS file: /cvsroot/jdbc/pgjdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java,v
retrieving revision 1.105
diff -u -r1.105 AbstractJdbc2ResultSet.java
--- org/postgresql/jdbc2/AbstractJdbc2ResultSet.java	30 Sep 2008 04:34:51 -0000	1.105
+++ org/postgresql/jdbc2/AbstractJdbc2ResultSet.java	16 Apr 2009 13:01:21 -0000
@@ -2137,6 +2137,65 @@
         return val;
     }
 
+    /**
+     * Optimised byte[] to number parser.  This code does not
+     * handle null values, so the caller must do checkResultSet
+     * and handle null values prior to calling this function.
+     * 
+     * @param columnIndex The column to parse.
+     * @return The parsed number.
+     * @throws SQLException If an error occurs while fetching column.
+     * @throws NumberFormatException If the number is invalid or the
+     * out of range for fast parsing. The value must then be parsed by
+     * {@link #toBigDecimal(String)}.
+     */
+    private BigDecimal getFastBigDecimal(int columnIndex) throws SQLException,
+        NumberFormatException {
+        
+        byte[] bytes = this_row[columnIndex - 1];
+        
+        if (bytes.length == 0) {
+            throw FAST_NUMBER_FAILED;
+        }
+        
+        int scale = 0;
+        long val = 0;
+        int start;
+        boolean neg;
+        if (bytes[0] == '-') {
+            neg = true;
+            start = 1;
+            if (bytes.length > 19) {
+                throw FAST_NUMBER_FAILED;
+            }
+        } else {
+            start = 0;
+            neg = false;
+            if (bytes.length > 18) {
+                throw FAST_NUMBER_FAILED;
+            }
+        }
+
+        while (start < bytes.length) {
+            byte b = bytes[start++];
+            if (b < '0' || b > '9') {
+            	if (b == '.') {
+            		scale = bytes.length - start;
+            		continue;
+            	} else
+            		throw FAST_NUMBER_FAILED;
+            }
+            val *= 10;
+            val += b - '0';
+        }
+        
+        if (neg) {
+            val = -val;
+        }        
+        
+        return BigDecimal.valueOf(val, scale);
+    }
+
     public float getFloat(int columnIndex) throws SQLException
     {
         checkResultSet(columnIndex);
@@ -2161,6 +2220,14 @@
         if (wasNullFlag)
             return null;
         
+        Encoding encoding = connection.getEncoding();
+        if (encoding.hasAsciiNumbers()) {
+            try {
+                return getFastBigDecimal(columnIndex);
+            } catch (NumberFormatException ex) {
+            }
+        }
+        
         return toBigDecimal( getFixedString(columnIndex), scale );
     }
 
В списке pgsql-jdbc по дате отправления
От: John Lister
Дата:
Сообщение: Re: Query preparation
От: Kris Jurka
Дата:
Сообщение: Re: Fast BigDecimal
FAQ