在 ImDisk RAM DISK 中以编程方式保存文件并不更快

Saving files programatically in ImDisk's RAM DISK is not faster

我使用 ImDisk, and compared reading/writing speeds of the HDD and Ram Disk with the simple benchmark software CrystalDiskMark 创建了一个 256MB 的 RAM 磁盘。 CrystalDiskMark 显示 RAM 磁盘比 HDD 快 10 倍,正如预期的那样。

但是,我尝试以编程方式将数据保存到 RAM 磁盘和 HDD,希望 RAM 磁盘更快,并且两者花费的时间相同。

我在 Java 中编写了以下代码,创建了一个 JAR 可执行文件,并 运行 在 HDD 和 Ram 磁盘中创建了可执行文件。此代码创建一个 16x16 的黑色图像,在本地保存 100 个不同的 PNG 文件副本,并在终端中打印保存每个文件所花费的时间、平均值和总时间。

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;

public class SaveImageSpeedTest {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        BufferedImage img = new BufferedImage(16, 16, BufferedImage.TYPE_3BYTE_BGR);

        long n = 100;
        long total_time = 0;
        for(long i=0; i<n; i++) {
            try {
                long time = System.nanoTime();
                ImageIO.write(img, "PNG", new File(i+".png"));
                time = System.nanoTime()-time;
                total_time += time;
                System.out.println((i+1)+"/"+n+" - "+"Time: "+(time/1000000L)+" ms");
            } catch (Exception ex) {
                Logger.getLogger(SaveImageSpeedTest.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        long average_time = total_time/n;
        System.out.println();
        System.out.println("Total time: "+(total_time/1000000L)+" ms");
        System.out.println("Average time: "+(average_time/1000000L)+" ms");
    }
}

这怎么可能?如果基准测试显示 RAM 磁盘快 10 倍,为什么它没有更快?我还尝试用 C++ 可执行文件保存数据,再次,时间是一样的。

编辑 1: 通过将 RAM 磁盘的格式从 NTFS 更改为 FAT,我的速度几乎提高了两倍,但应该提高 10 倍。

编辑 2: 我尝试了不同的图像尺寸,甚至制作了 运行dom 图像(以避免缓存数据)。结果始终相同:Ram DISK 的速度几乎是原来的两倍。

当您写入文件时,它 does not yet mean that the data is actually written to a disk. Operating Systems typically use buffer cache to defer writes 到设备。

因此,您的基准测试主要衡量图像编码和写入缓冲区缓存的性能。如果要测量实际设备 I/O,性能测试至少应涉及 FileChannel.force (which calls fsync 底层)。

除此之外,从基准测试中排除图像编​​码,因为它也可能需要大量时间。