Skip to content

Instantly share code, notes, and snippets.

@apangin
Last active November 11, 2016 11:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apangin/b02ffe663a64d3d9ed8c2cfa680d61dc to your computer and use it in GitHub Desktop.
Save apangin/b02ffe663a64d3d9ed8c2cfa680d61dc to your computer and use it in GitHub Desktop.
BufferedOutputStream performance
import java.io.*;
public class BenchmarkTest {
public static void main( String[] args ) throws IOException {
testNoSync(100_000);
testSync(100_000);
while( true ) {
testNoSync(100_000_000);
testSync(100_000_000);
}
}
static void testNop( int loops ) throws IOException {
BenchmarkTest test = new BenchmarkTest();
test.out = new OutputStream() {
@Override
public void write( int b ) throws IOException {
// nop
}
};
test.run( " nop OutputStream", loops );
}
static void testSync( int loops ) throws IOException {
BenchmarkTest test = new BenchmarkTest();
test.out = new BufferedOutputStream( new OutputStream() {
@Override
public void write( int b ) throws IOException {
// nop
}
}, 32768 );
test.run( " sync BufferedOutputStream", loops );
}
static void testNoSync( int loops ) throws IOException {
BenchmarkTest test = new BenchmarkTest();
test.out = new FastBufferedOutputStream( new OutputStream() {
@Override
public void write( int b ) throws IOException {
// nop
}
}, 32768 );
test.run( "no sync BufferedOutputStream", loops );
}
private OutputStream out;
void run( String testName, int loops ) throws IOException {
long time = System.currentTimeMillis();
OutputStream out = this.out;
synchronized (out) {
for( int i = 0; i < loops; i++ ) {
out.write( i );
}
}
System.out.println( testName + " time: " + (System.currentTimeMillis() - time) );
}
static public class FastBufferedOutputStream extends OutputStream {
private byte[] buf;
private int count;
private OutputStream out;
/**
* Creates a BufferedOutputStream without synchronized.
*
* @param out the underlying output stream.
*/
public FastBufferedOutputStream( OutputStream out ) {
this( out, 8192 );
}
/**
* Creates a BufferedOutputStream without synchronized.
*
* @param out the underlying output stream.
* @param size the buffer size.
* @exception IllegalArgumentException if size &lt;= 0.
*/
public FastBufferedOutputStream( OutputStream out, int size ) {
this.out = out;
this.buf = new byte[size];
}
/**
* Flush the internal buffer
*
* @throws IOException if any I/O error occur
*/
private void flushBuffer() throws IOException {
if( count > 0 ) {
out.write( buf, 0, count );
count = 0;
}
}
/**
* {@inheritDoc}
*/
@Override
public void write( int b ) throws IOException {
if( count >= buf.length ) {
flushBuffer();
}
buf[count++] = (byte)b;
}
/**
* {@inheritDoc}
*/
@Override
public void write( byte[] b, int off, int len ) throws IOException {
if( len >= buf.length ) {
/* If the request length exceeds the size of the output buffer,
flush the output buffer and then write the data directly.
In this way buffered streams will cascade harmlessly. */
flushBuffer();
out.write( b, off, len );
return;
}
if( len > buf.length - count ) {
flushBuffer();
}
System.arraycopy( b, off, buf, count, len );
count += len;
}
/**
* {@inheritDoc}
*/
@Override
public void flush() throws IOException {
flushBuffer();
out.flush();
}
/**
* {@inheritDoc}
*/
@Override
public void close() throws IOException {
flushBuffer();
out.close();
}
}
}
no sync BufferedOutputStream time: 15
sync BufferedOutputStream time: 0
no sync BufferedOutputStream time: 215
sync BufferedOutputStream time: 202
no sync BufferedOutputStream time: 201
sync BufferedOutputStream time: 199
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment