Index: org/postgresql/core/Utils.java =================================================================== RCS file: /cvsroot/jdbc/pgjdbc/org/postgresql/core/Utils.java,v retrieving revision 1.7 diff -u -r1.7 Utils.java --- org/postgresql/core/Utils.java 8 Jan 2008 06:56:27 -0000 1.7 +++ org/postgresql/core/Utils.java 2 Jun 2008 08:08:59 -0000 @@ -11,7 +11,16 @@ package org.postgresql.core; +import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.CharacterCodingException; +import java.nio.CharBuffer; +import java.nio.ByteBuffer; + import java.sql.SQLException; +import java.util.Arrays; + import org.postgresql.util.GT; import org.postgresql.util.PSQLException; @@ -38,6 +47,10 @@ return sb.toString(); } + // Keep a local copy of the UTF-8 Charset so we can avoid + // synchronization overhead with getBytes() + private static final Charset UTF8_CHARSET = Charset.forName("UTF-8"); + private static final byte[] EMPTY_BYTEARRAY = new byte[0]; /** * Encode a string as UTF-8. * @@ -49,15 +62,18 @@ // faster than rolling our own converter (it uses direct buffers and, I suspect, // a native helper -- and the cost of the encoding lookup is mitigated by a // ThreadLocal that caches the last lookup). So we just do things the simple way here. - try - { - return str.getBytes("UTF-8"); - } - catch (java.io.UnsupportedEncodingException e) - { - // Javadoc says that UTF-8 *must* be supported by all JVMs, so we don't try to be clever here. - throw new RuntimeException("Unexpected exception: UTF-8 charset not supported: " + e); - } + // + // Updated: It turns out that Java is particularly bad at caching more than 2 character sets + // so it's better to use the underlying nio classes here to perform the UTF-8 + // conversion with a local copy of the UTF-8 Charset object. + // + if (str == null) { + return EMPTY_BYTEARRAY; + } + ByteBuffer buf = UTF8_CHARSET.encode(CharBuffer.wrap(str)); + byte[] b = new byte[buf.limit()]; + buf.get(b, 0, buf.limit()); + return b; } /**