Fast BigDecimal

Поиск
Список
Период
Сортировка
От Heikki Linnakangas
Тема Fast BigDecimal
Дата
Msg-id 49E72C90.9010903@enterprisedb.com
обсуждение исходный текст
Ответы Re: Fast BigDecimal  (Kris Jurka <books@ejurka.com>)
Unit tests and ordering  (John Lister <john.lister-ps@kickstone.com>)
Список pgsql-jdbc
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