RE: JDBC driver GREATLY speeded up by trivial fix

From: Peter Mount <petermount(at)it(dot)maidstone(dot)gov(dot)uk>
To: "'William Chesters'" <williamc(at)paneris(dot)org>, pgsql-interfaces(at)postgresql(dot)org
Cc: melati_development(at)messageboards(dot)paneris(dot)org
Subject: RE: JDBC driver GREATLY speeded up by trivial fix
Date: 2000-07-31 07:36:37
Message-ID: 1B3D5E532D18D311861A00600865478CF1B184@exchange1.nt.maidstone.gov.uk
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-interfaces

The getTimestamp() problem has been discussed a lot on this list recently.
I'm currently having horrible problems with my home system (hasn't recovered
well after the move) so I've not been able to sit down and apply the fixes.

As for receiveString(), it predates the driver merger (some 2 years ago?) so
as it's never broke it's been left. I suspect there's a lot of little
performace gems in there if we had time to sit down and do them.

Peter

--
Peter Mount
Enterprise Support
Maidstone Borough Council
Any views stated are my own, and not those of Maidstone Borough Council

-----Original Message-----
From: William Chesters [mailto:williamc(at)paneris(dot)org]
Sent: Sunday, July 30, 2000 5:21 PM
To: pgsql-interfaces(at)postgresql(dot)org
Cc: melati_development(at)messageboards(dot)paneris(dot)org
Subject: [INTERFACES] JDBC driver GREATLY speeded up by trivial fix

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 William Chesters 2000-07-31 08:29:59 RE: JDBC driver GREATLY speeded up by trivial fix
Previous Message Cedar Cox 2000-07-31 07:22:31 PGAccess and UNIX sockets