Java:通过Techannel收集优势?
我想知道的是,与“常规”的可写ByTechannel写入方法相比,的写入方法(接受ByteBuffers数组)何时具有优势 我尝试了一个测试,在这个测试中,我可以在一个文件通道上使用常规写入方法和聚集写入方法,在这两种情况下,字节缓冲区的总长度都在23-27字节之间,大约为400KB/秒。收集写入使用了64的数组。常规方法使用了大约12%的CPU,而收集方法使用了大约16%的CPU(比常规方法更糟糕!) 这告诉我,围绕此操作参数范围在FileChannel上使用聚集写入是没有用的。为什么会出现这种情况?您何时会使用GatheringByteChannel?(在网络I/O上?) 相关差异如下:Java:通过Techannel收集优势?,java,nio,Java,Nio,我想知道的是,与“常规”的可写ByTechannel写入方法相比,的写入方法(接受ByteBuffers数组)何时具有优势 我尝试了一个测试,在这个测试中,我可以在一个文件通道上使用常规写入方法和聚集写入方法,在这两种情况下,字节缓冲区的总长度都在23-27字节之间,大约为400KB/秒。收集写入使用了64的数组。常规方法使用了大约12%的CPU,而收集方法使用了大约16%的CPU(比常规方法更糟糕!) 这告诉我,围绕此操作参数范围在FileChannel上使用聚集写入是没有用的。为什么会出现这
public void log(Queue<Packet> packets) throws IOException
{
if (this.gather)
{
int Nbuf = 64;
ByteBuffer[] bbufs = new ByteBuffer[Nbuf];
int i = 0;
Packet p;
while ((p = packets.poll()) != null)
{
bbufs[i++] = p.getBuffer();
if (i == Nbuf)
{
this.fc.write(bbufs);
i = 0;
}
}
if (i > 0)
{
this.fc.write(bbufs, 0, i);
}
}
else
{
Packet p;
while ((p = packets.poll()) != null)
{
this.fc.write(p.getBuffer());
}
}
}
packets.poll()是否每次创建新的缓冲区时都会创建?如果没有,则在第一种情况下,您写入的数据是错误的。您可能不希望使用超过16个缓冲区进行读取或写入。我知道,由于Solaris的限制,Java5的硬限制为16(可以接受更多,但只能读/写其中的16个)。
enum GatherType { NONE, AUTOMATIC, MANUAL }
static class BufferWriter
{
final private FileChannel fc;
private GatherType gather = GatherType.NONE;
BufferWriter(FileChannel f) { this.fc = f; }
public void setGather(GatherType gather) { this.gather=gather; }
public void write(Queue<ByteBuffer> buffers) throws IOException
{
switch (this.gather)
{
case AUTOMATIC:
{
int Nbuf = 64;
ByteBuffer[] bbufs = new ByteBuffer[Nbuf];
int i = 0;
ByteBuffer b;
while ((b = buffers.poll()) != null)
{
bbufs[i++] = b;
if (i == Nbuf)
{
this.fc.write(bbufs);
i = 0;
}
}
if (i > 0)
{
this.fc.write(bbufs, 0, i);
}
}
break;
case MANUAL:
{
ByteBuffer consolidatedBuffer = ByteBuffer.allocate(4096);
ByteBuffer b;
while ((b = buffers.poll()) != null)
{
if (b.remaining() > consolidatedBuffer.remaining())
{
consolidatedBuffer.flip();
this.fc.write(consolidatedBuffer);
consolidatedBuffer.clear();
}
if (b.remaining() > consolidatedBuffer.remaining())
{
this.fc.write(b);
}
else
{
consolidatedBuffer.put(b);
}
}
consolidatedBuffer.flip();
if (consolidatedBuffer.hasRemaining())
{
this.fc.write(consolidatedBuffer);
}
}
break;
case NONE:
{
ByteBuffer b;
while ((b = buffers.poll()) != null)
{
this.fc.write(b);
}
}
break;
}
}
}