我对mmap vs读写性能进行了测试,然后得到了这些真实数据:
所以我得出以下结论:
我的结论正确吗?
我的一位同事说,他对mmap的印象比fileChannel的随机读取性能差。我的测试过程正确吗?
测试环境:32核CPU,96G内存,3T磁盘(SATA),centOS 6.0
我的测试代码:
public class Main {
public static void mmap_random_write() throws Exception{
Random random = new Random() ;
RandomAccessFile randomAccessFile = new RandomAccessFile("file.txt" , "rw") ;
FileChannel fileChannel = randomAccessFile.getChannel() ;
ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 4); //4K buffer
for (int i = 0; i < 1024 * 4; i++) {
byteBuffer.put((byte) 1);
}
long start = System.nanoTime() ;
int size = 1024 * 1024 * 1024 ;
MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, size);
for(int i=0 ; i<1000*10000 ; i++){
byteBuffer.flip();
int offset = random.nextInt(size - 4*1024) ;
mappedByteBuffer.position(offset) ;
mappedByteBuffer.put(byteBuffer) ;
}
long end = System.nanoTime() ;
System.out.println((end - start) + ": mmap random write") ;
fileChannel.close();
}
public static void mmap_random_read() throws Exception{
RandomAccessFile randomAccessFile = new RandomAccessFile("file.txt" , "rw") ;
FileChannel fileChannel = randomAccessFile.getChannel() ;
byte[] bytes = new byte[4*1024] ;
ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 4);
for (int i = 0; i < 1024 * 4; i++) {
byteBuffer.put((byte) 1);
}
long start = System.nanoTime() ;
int size = 1024 * 1024 * 1024 ;
MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, size);
Random random = new Random() ;
for(long i=0 ; i<1000*10000; i++){
int offset = random.nextInt(size - 4*1024) ;
mappedByteBuffer.position(offset) ;
mappedByteBuffer.get(bytes) ;
}
long end = System.nanoTime() ;
System.out.println((end - start) + ": mmap random read");
fileChannel.close();
}
public static void mmap_order_read() throws Exception{
FileChannel[] fileChannels = new FileChannel[100] ;
for(int i=0 ; i<100 ; i++){
RandomAccessFile randomAccessFile = new RandomAccessFile("file" + i + ".txt" , "rw") ;
FileChannel fileChannel = randomAccessFile.getChannel() ;
fileChannels[i] = fileChannel ;
}
byte[] bytes = new byte[4*1024] ;
ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 4);
for (int i = 0; i < 1024 * 4; i++) {
byteBuffer.put((byte) 1);
}
long start = System.nanoTime() ;
for(int i=0 ; i<fileChannels.length ; i++){
int size = 1024 * 1024 * 1024 ;
FileChannel fileChannel = fileChannels[i] ;
MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, size);
int writeCount = size / (4 * 1024);
for (int count = 0; count < writeCount; count++) {
byteBuffer.flip();
mappedByteBuffer.get(bytes) ;
}
}
long end = System.nanoTime() ;
System.out.println((end - start) + ":mmap order read");
for(FileChannel fileChannel : fileChannels){
fileChannel.close();
}
}
public static void mmap_order_write() throws Exception{
FileChannel[] fileChannels = new FileChannel[100] ;
for(int i=0 ; i<100 ; i++){
RandomAccessFile randomAccessFile = new RandomAccessFile("mmap" + i + ".txt" , "rw") ;
FileChannel fileChannel = randomAccessFile.getChannel() ;
fileChannels[i] = fileChannel ;
}
ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 4);
for (int i = 0; i < 1024 * 4; i++) {
byteBuffer.put((byte) 1);
}
long start = System.nanoTime() ;
for(int i=0 ; i<fileChannels.length ; i++){
int size = 1024 * 1024 * 1024 ;
FileChannel fileChannel = fileChannels[i] ;
MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, size);
int writeCount = size / (4 * 1024);
for (int count = 0; count < writeCount; count++) {
byteBuffer.flip();
mappedByteBuffer.put(byteBuffer) ;
}
}
long end = System.nanoTime() ;
System.out.println((end - start) + ":mmap order write");
for(FileChannel fileChannel : fileChannels){
fileChannel.close();
}
}
public static void channel_order_write() throws Exception {
FileChannel[] fileChannels = new FileChannel[100] ;
for(int i=0 ; i<100 ; i++){
RandomAccessFile randomAccessFile = new RandomAccessFile("fileChannel" + i + ".txt" , "rw") ;
FileChannel fileChannel = randomAccessFile.getChannel() ;
fileChannels[i] = fileChannel ;
}
ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 4);
for (int i = 0; i < 1024 * 4; i++) {
byteBuffer.put((byte) 1);
}
long start = System.nanoTime() ;
for(int i=0 ; i<fileChannels.length ; i++){
int size = 1024 * 1024 * 1024 ;
FileChannel fileChannel = fileChannels[i] ;
int writeCount = size / (4 * 1024);
for (int count = 0; count < writeCount; count++) {
byteBuffer.flip();
fileChannel.write(byteBuffer) ;
}
}
long end = System.nanoTime() ;
System.out.println((end - start) + ":read() and write() order write");
for(FileChannel fileChannel : fileChannels){
fileChannel.close();
}
}
public static void channel_order_read() throws Exception{
FileChannel[] fileChannels = new FileChannel[100] ;
for(int i=0 ; i<100 ; i++){
RandomAccessFile randomAccessFile = new RandomAccessFile("file" + i + ".txt" , "rw") ;
FileChannel fileChannel = randomAccessFile.getChannel() ;
fileChannels[i] = fileChannel ;
}
ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 4);
for (int i = 0; i < 1024 * 4; i++) {
byteBuffer.put((byte) 1);
}
long start = System.nanoTime() ;
for(int i=0 ; i<fileChannels.length ; i++){
int size = 1024 * 1024 * 1024 ;
FileChannel fileChannel = fileChannels[i] ;
int writeCount = size / (4 * 1024);
for (int count = 0; count < writeCount; count++) {
byteBuffer.rewind();
fileChannel.read(byteBuffer) ;
}
}
long end = System.nanoTime() ;
System.out.println((end - start) + ":read() and write() order read");
for(FileChannel fileChannel : fileChannels){
fileChannel.close();
}
}
public static void channel_random_read()throws Exception{
RandomAccessFile randomAccessFile = new RandomAccessFile("file.txt" , "rw") ;
FileChannel fileChannel = randomAccessFile.getChannel() ;
ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 4);
for (int i = 0; i < 1024 * 4; i++) {
byteBuffer.put((byte) 1);
}
long start = System.nanoTime() ;
int size = 1024 * 1024 * 1024 ;
Random random = new Random() ;
for(int i=0 ; i<1000*10000 ; i++){
byteBuffer.rewind();
int offset = random.nextInt(size - 4*1024) ;
fileChannel.position(offset) ;
fileChannel.read(byteBuffer) ;
}
long end = System.nanoTime() ;
System.out.println((end - start) + ":read() and write() random read");
fileChannel.close();
}
public static void channel_random_write()throws Exception {
Random random = new Random() ;
RandomAccessFile randomAccessFile = new RandomAccessFile("file.txt" , "rw") ;
FileChannel fileChannel = randomAccessFile.getChannel() ;
ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 4);
for (int i = 0; i < 1024 * 4; i++) {
byteBuffer.put((byte) 1);
}
long start = System.nanoTime() ;
int size = 1024 * 1024 * 1024 ;
for(int i=0 ; i<1000*10000 ; i++){
byteBuffer.flip();
int offset = random.nextInt(size - 4*1024) ;
fileChannel.position(offset) ;
fileChannel.write(byteBuffer) ;
}
long end = System.nanoTime() ;
System.out.println((end - start) + ":read() and write() random write");
fileChannel.close();
}
}