Thread: JDBC: Better initial capacity for StringBuffers reduces memory usage
Regardless of the streaming patches that are floating around, we should fix the allocation of the StringBuffers. On the AbstractJdbc1Statement one, the initial space allocated for the buffer will never be enough because of the quotes, so we end up using 3 times the size of the object + 1 and having to copy it from the initial buffer to the double size one. Instead of just adding '+2' I gave it some slack for the escaping of quotes. The one in PGbytea may raise some eyebrows, but I can guarantee you that it _always_ win, when compared to allocate just the object size for at least that amount of space. The changes above reduce by 33% (in the worst case) the memory requirements for uploading data (without the streaming patches). Although not that important for smaller data types (once the streaming is in place we will not send large ones through this path anymore), there is no reason to waste memory so I suggest we check this in. Regards to all. -- Fernando Nasser Red Hat - Toronto E-Mail: fnasser@redhat.com 2323 Yonge Street, Suite #300 Toronto, Ontario M4P 2C9 Index: src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java,v retrieving revision 1.21 diff -c -p -r1.21 AbstractJdbc1Statement.java *** src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java 2003/05/03 20:40:45 1.21 --- src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java 2003/05/14 05:58:21 *************** public abstract class AbstractJdbc1State *** 1020,1026 **** synchronized (sbuf) { sbuf.setLength(0); ! sbuf.ensureCapacity(x.length()); int i; sbuf.append('\''); --- 1020,1026 ---- synchronized (sbuf) { sbuf.setLength(0); ! sbuf.ensureCapacity(x.length() + (int)(x.length() / 10)); int i; sbuf.append('\''); Index: src/interfaces/jdbc/org/postgresql/util/PGbytea.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/util/PGbytea.java,v retrieving revision 1.7 diff -c -p -r1.7 PGbytea.java *** src/interfaces/jdbc/org/postgresql/util/PGbytea.java 2003/03/07 18:39:46 1.7 --- src/interfaces/jdbc/org/postgresql/util/PGbytea.java 2003/05/14 05:58:22 *************** public class PGbytea *** 68,74 **** { if (p_buf == null) return null; ! StringBuffer l_strbuf = new StringBuffer(p_buf.length); for (int i = 0; i < p_buf.length; i++) { int l_int = (int)p_buf[i]; --- 68,74 ---- { if (p_buf == null) return null; ! StringBuffer l_strbuf = new StringBuffer(2 * p_buf.length); for (int i = 0; i < p_buf.length; i++) { int l_int = (int)p_buf[i];
Fernando, Patch applied to CVS head. thanks, --Barry Fernando Nasser wrote: > Regardless of the streaming patches that are floating around, we should > fix the allocation of the StringBuffers. > > On the AbstractJdbc1Statement one, the initial space allocated for the > buffer will never be enough because of the quotes, so we end up using 3 > times the size of the object + 1 and having to copy it from the initial > buffer to the double size one. Instead of just adding '+2' I gave it > some slack for the escaping of quotes. > > The one in PGbytea may raise some eyebrows, but I can guarantee you that > it _always_ win, when compared to allocate just the object size for at > least that amount of space. > > The changes above reduce by 33% (in the worst case) the memory > requirements for uploading data (without the streaming patches). > Although not that important for smaller data types (once the streaming > is in place we will not send large ones through this path anymore), > there is no reason to waste memory so I suggest we check this in. > > Regards to all. > > > > ------------------------------------------------------------------------ > > Index: src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java,v > retrieving revision 1.21 > diff -c -p -r1.21 AbstractJdbc1Statement.java > *** src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java 2003/05/03 20:40:45 1.21 > --- src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java 2003/05/14 05:58:21 > *************** public abstract class AbstractJdbc1State > *** 1020,1026 **** > synchronized (sbuf) > { > sbuf.setLength(0); > ! sbuf.ensureCapacity(x.length()); > int i; > > sbuf.append('\''); > --- 1020,1026 ---- > synchronized (sbuf) > { > sbuf.setLength(0); > ! sbuf.ensureCapacity(x.length() + (int)(x.length() / 10)); > int i; > > sbuf.append('\''); > Index: src/interfaces/jdbc/org/postgresql/util/PGbytea.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/util/PGbytea.java,v > retrieving revision 1.7 > diff -c -p -r1.7 PGbytea.java > *** src/interfaces/jdbc/org/postgresql/util/PGbytea.java 2003/03/07 18:39:46 1.7 > --- src/interfaces/jdbc/org/postgresql/util/PGbytea.java 2003/05/14 05:58:22 > *************** public class PGbytea > *** 68,74 **** > { > if (p_buf == null) > return null; > ! StringBuffer l_strbuf = new StringBuffer(p_buf.length); > for (int i = 0; i < p_buf.length; i++) > { > int l_int = (int)p_buf[i]; > --- 68,74 ---- > { > if (p_buf == null) > return null; > ! StringBuffer l_strbuf = new StringBuffer(2 * p_buf.length); > for (int i = 0; i < p_buf.length; i++) > { > int l_int = (int)p_buf[i]; > > > ------------------------------------------------------------------------ > > > ---------------------------(end of broadcast)--------------------------- > TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org