JDBC driver GREATLY speeded up by trivial fix

From: William Chesters <williamc(at)paneris(dot)org>
To: pgsql-interfaces(at)postgresql(dot)org
Cc: melati_development(at)messageboards(dot)paneris(dot)org
Subject: JDBC driver GREATLY speeded up by trivial fix
Date: 2000-07-30 16:21:08
Message-ID: 200007301621.SAA02908@beertje.william.bogus
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-interfaces

First, sorry if this has been discussed before---I'm working with
the JDBC driver from the Postgresql 7.0 distribution.

I recently had occasion to run a profiler over an app, and
discovered that it was spending a lot of its time at the following
line in org.postgresql.PG_Stream.ReceiveString:

byte[] rst = new byte[maxsiz];

The point is that maxsiz is typically 8192, while the number of bytes
actually read into the buffer is the length of a field name
(i.e. never more than about 20). The resulting performance hit is
absolutely horrendous---the fact that the poor JVM has to
zero-initialise the array is bad enough, but think of the effect on
the CPU cache and the garbage collector!

My replacement for this routine is given below. It's not obviously
the fastest possible implementation, but the effect on the performance
of database-intensive applications is just _unreal_: I mean integer
factors, rather than a few percent.

I don't want to diss the efforts of the drivers' authors, but I
couldn't help noticing a few other horrors lurking around, like in
ResultSet.getDate and .getTimestamp both doing new SimpleDateFormat
every time they are called, which is pretty expensive if you look at
Sun's sources. [Incidentally .getTimestamp is broken by the 7.0
backend ...] Is it being actively maintained? Can I help?

Best wishes,
William

private static final class FinalByteArrayOutputStream
extends ByteArrayOutputStream {
public FinalByteArrayOutputStream(int size) {
super(size);
}
}

/**
* Receives a null-terminated string from the backend. Maximum of
* maxsiz bytes - if we don't see a null, then we assume something
* has gone wrong.
*
* @param maxsiz maximum length of string
* @return string from back end
* @exception SQLException if an I/O error occurs
*/

public String ReceiveString(int maxsiz) throws SQLException
{
FinalByteArrayOutputStream buf = new FinalByteArrayOutputStream(20);

try {
for (;;) {
if (buf.size() >= maxsiz)
throw new PSQLException("postgresql.stream.toomuch");

int c = pg_input.read();
if (c < 0)
throw new PSQLException("postgresql.stream.eof");
else if (c == 0)
break;
else
buf.write(c);
}
}
catch (IOException e) {
throw new PSQLException("postgresql.stream.ioerror",e);
}

return buf.toString(0);
}

Responses

Browse pgsql-interfaces by date

  From Date Subject
Next Message David Lloyd-Jones 2000-07-30 19:23:44 Re: PSQL Working, but PGAccess Not Connecting.
Previous Message Tim Uckun 2000-07-29 02:49:53 Access and Postgres question.