Thread: 8.2 driver getBoolean(...) performance question

8.2 driver getBoolean(...) performance question

From
"Fear, Jake"
Date:

I’ve been profiling an application using both the 8.1 and 8.2 drivers (congratulations on the improvements!) and I have a question regarding the order in which the values in the method AbstractJdbc2ResultSet are interpreted:

 

Here is the  block of code in question:

 

            if (s.equalsIgnoreCase("t") || s.equalsIgnoreCase("true") || s.equals("1"))

                return true;

 

            if (s.equalsIgnoreCase("f") || s.equalsIgnoreCase("false") || s.equals("0"))

                return false;

 

It checks t then true then 1, but the code in the method AbstractJdbc2Statement.setBoolean:

    public void setBoolean(int parameterIndex, boolean x) throws SQLException

    {

        checkClosed();

        bindString(parameterIndex, x ? "1" : "0", Oid.BOOL);

    }

 

Seems to indicate the 0 or 1, if the drivers are being used as expected, will be the preferred values, and would make sense on the left hand site of the short-circuiting || operation in the result set class.

 

The getBoolean method isn’t nearly as high in the profiler as it was on the 8.1 drivers, but it is still showing up consuming more CPU than I would expect.

 

So my question is this:  Is there anything I’m missing that actually makes the t/f values the preferred test?  Am I missing something on the statement side that makes this more efficient?  In my particular case (using Hibernate and explicitly using boolean data types) putting the 0/1 test first is more efficient.

 

Thanks,

 

Jake Fear

Software Engineering Supervisor

Sony Online Entertainment

858-790-3526

 

Re: 8.2 driver getBoolean(...) performance question

From
Kris Jurka
Date:

On Fri, 13 Apr 2007, Fear, Jake wrote:

> I've been profiling an application using both the 8.1 and 8.2 drivers
> (congratulations on the improvements!) and I have a question regarding
> the order in which the values in the method AbstractJdbc2ResultSet are
> interpreted:
>
>            if (s.equalsIgnoreCase("t") || s.equalsIgnoreCase("true") ||
> s.equals("1"))
>
> It checks t then true then 1, but the code in the method
> AbstractJdbc2Statement.setBoolean:
>
>        bindString(parameterIndex, x ? "1" : "0", Oid.BOOL);
>
> Seems to indicate the 0 or 1, if the drivers are being used as expected,
> will be the preferred values, and would make sense on the left hand site
> of the short-circuiting || operation in the result set class.
>
> The getBoolean method isn't nearly as high in the profiler as it was on
> the 8.1 drivers, but it is still showing up consuming more CPU than I
> would expect.
>
> So my question is this:  Is there anything I'm missing that actually
> makes the t/f values the preferred test?  Am I missing something on the
> statement side that makes this more efficient?  In my particular case
> (using Hibernate and explicitly using boolean data types) putting the
> 0/1 test first is more efficient.
>

Depends what the underlying data type is.  If you use pg's boolean
datatype you get "t":

# select '1'::boolean;
  bool
------
  t
(1 row)

We use 1/0 on the set call because we don't know what the underlying
datatype will be.  If someone has a numeric type then 1/0 will do
something useful while t/f won't.  The only potential improvement to
getBoolean might be to do:

s.equals("t") || s.equalsIgnoreCase("t") || ...

If we assume that most calls will be upon a boolean type then the case
insensitivity is just slowing us down.

For your case you should check the hibernate mapping and ensure that it is
using a true boolean type instead of a numeric type.

Kris Jurka