我被要求衡量当前的磁盘性能,因为我们计划用应用程序服务器上的网络连接存储替换本地磁盘。由于我们写数据的应用程序是用Java编写的,所以我认为我将直接在Linux上并使用简单的Java测试来测量性能。但是,我得到的结果截然不同,尤其是在读取数据时,使用我认为类似的测试。直接在Linux中,我正在做:

dd if=/dev/zero of=/data/cache/test bs=1048576 count=8192
dd if=/data/cache/test of=/dev/null bs=1048576 count=8192


我的Java测试如下所示:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class TestDiskSpeed {
private byte[] oneMB = new byte[1024 * 1024];

public static void main(String[] args) throws IOException {
    new TestDiskSpeed().execute(args);
}

private void execute(String[] args) throws IOException {
    long size = Long.parseLong(args[1]);
    testWriteSpeed(args[0], size);
    testReadSpeed(args[0], size);
}


private void testWriteSpeed(String filePath, long size) throws IOException {
    File file = new File(filePath);
    BufferedOutputStream writer = null;
    long start = System.currentTimeMillis();
    try {
        writer = new BufferedOutputStream(new FileOutputStream(file), 1024 * 1024);
        for (int i = 0; i < size; i++) {
            writer.write(oneMB);
        }
        writer.flush();
    } finally {
        if (writer != null) {
            writer.close();
        }
    }
    long elapsed = System.currentTimeMillis() - start;
    String message = "Wrote " + size + "MB in " + elapsed + "ms at a speed of " + calculateSpeed(size, elapsed) + "MB/s";
    System.out.println(message);
}

private void testReadSpeed(String filePath, long size) throws IOException {
    File file = new File(filePath);
    BufferedInputStream reader = null;
    long start = System.currentTimeMillis();
    try {
        reader = new BufferedInputStream(new FileInputStream(file), 1024 * 1024);
        for (int i = 0; i < size; i++) {
            reader.read(oneMB);
        }
    } finally {
        if (reader != null) {
            reader.close();
        }
    }
    long elapsed = System.currentTimeMillis() - start;
    String message = "Read " + size + "MB in " + elapsed + "ms at a speed of " + calculateSpeed(size, elapsed) + "MB/s";
    System.out.println(message);
}

private double calculateSpeed(long size, long elapsed) {
    double seconds = ((double) elapsed) / 1000L;
    double speed = ((double) size) / seconds;
    return speed;
}


}

这是通过“ java TestDiskSpeed / data / cache / test 8192”来调用的

两者都应创建8GB的零文件,一次创建1MB,测量速度,然后回读并再次测量。但是我一直得到的速度是:

Linux:写入-约650MB / s

Linux:读取-〜4.2GB / s

Java:写入-〜500MB / s

Java:读取-〜1.9GB / s

谁能解释这个大差异?

最佳答案

当我在系统上使用NIO运行它时。配备i7-3970X的Ubuntu 15.04

public class Main {
    static final int SIZE_GB = Integer.getInteger("sizeGB", 8);
    static final int BLOCK_SIZE = 64 * 1024;

    public static void main(String[] args) throws IOException {
        ByteBuffer buffer = ByteBuffer.allocateDirect(BLOCK_SIZE);
        File tmp = File.createTempFile("delete", "me");
        tmp.deleteOnExit();
        int blocks = (int) (((long) SIZE_GB << 30) / BLOCK_SIZE);
        long start = System.nanoTime();
        try (FileChannel fc = new FileOutputStream(tmp).getChannel()) {
            for (int i = 0; i < blocks; i++) {
                buffer.clear();
                while (buffer.remaining() > 0)
                    fc.write(buffer);
            }
        }
        long mid = System.nanoTime();
        try (FileChannel fc = new FileInputStream(tmp).getChannel()) {
            for (int i = 0; i < blocks; i++) {
                buffer.clear();
                while (buffer.remaining() > 0)
                    fc.read(buffer);
            }
        }
        long end = System.nanoTime();

        long size = tmp.length();
        System.out.printf("Write speed %.1f GB/s, read Speed %.1f GB/s%n",
                (double) size/(mid-start), (double) size/(end-mid));

    }
}


版画

Write speed 3.8 GB/s, read Speed 6.8 GB/s

09-20 15:38