这个测试结果正确吗? mmap和写入性能测试

时间:2018-08-12 15:20:52

标签: java linux io mmap

我对mmap vs读写性能进行了测试,然后得到了这些真实数据:

  • 命令写入文件100G(写入前文件不存在)
    • mmap花费141780毫秒。
    • 读写成本127755ms。
  • 订购读取文件100G
    • mmap花费99166ms。
    • 读写成本80502ms。
  • 在1G文件中随机写入1000w次
    • mmap花费8844毫秒。
    • 读写成本43572ms。
  • 在1G文件中随机读取1000w次
    • mmap耗费7541毫秒。
    • 读写成本25199ms。

所以我得出以下结论:

  • 命令读写:mmap的性能比读写好得多
  • 随机读写:mmap的性能优于读写,

我的结论正确吗?


我的一位同事说,他对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();
}
}

0 个答案:

没有答案