【问题标题】:Latency spikes in android when writting to file写入文件时android中的延迟峰值
【发布时间】:2015-01-23 13:49:55
【问题描述】:

我正在运行一些性能测试,并在我的测试结果中看到一些峰值。 这是我用来测量写入文件时间的代码。

public class Test extends AndroidTestCase {

private DecimalFormat decimalFormat = new DecimalFormat("#.##");
private final Boolean isInternal = true;

public void testWrite() {
    Thread thread = new Thread() {
        public void run() {
            File dummy_file = createFile("dummy2", true);
            File file = createFile("normal_write", isInternal);
            for (int i = 0; i < 12500; i++) {
                long start = System.nanoTime();
                write(dummy_file, String.valueOf(i));
                long stop = System.nanoTime();
                double mSec = ((double) (stop - start) / 1000000.0);
                write(file, decimalFormat.format(mSec));
            }
        }
    };

    thread.start();

    try {
        thread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public File createFile(String fileName, Boolean isInternal) {
    deleteFile(fileName, isInternal);
    try {
        String file_path = "";
        if(isInternal == true) {
            file_path = getContext().getFilesDir().getAbsolutePath() + "/" + fileName + ".dat";
        } else {
            file_path = Environment.getExternalStorageDirectory() + "/" + fileName + ".dat";
        }
        File file = new File(file_path);
        file.createNewFile();
        FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write("##;##\n" +
                "@LiveGraph demo file.\n" +
                "Time");
        bw.newLine();
        bw.close();
        return file;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

public void deleteFile(String fileName, Boolean isInternal) {
    String file_path = "";
    if ( isInternal == true) {
        file_path = getContext().getFilesDir().getAbsolutePath() + "/" + fileName + ".dat";
    } else {
        file_path = Environment.getExternalStorageDirectory() + "/" + fileName + ".dat";
    }
    File file = new File(file_path);
    file.delete();
}

public void write(File file, String content) {
    try {
        FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write(content);
        bw.newLine();
        bw.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

大多数情况下,写入所需的时间约为 0.1-0.2 毫秒,但有些峰值需要 10 多毫秒,无法弄清楚这是什么原因。由于我是这里的新用户,我现在无法在此处链接图表。

我真的坚持这个有什么想法吗?

这是时间测量的一部分。

0.16 0.16 0.17 0.15 0.15 2.5 0.17 0.16 0.16 0.16 0.15 0.17 0.17 0.17 0.19 0.19 0.17 0.2 0 0 4.79 0.24 0.23 0.28 0.23 0.28 0.03 0 11.23 0.16 0.15 0.18 0.16 0.16 0.17 0.16 5.84

【问题讨论】:

    标签: android performance testing file-io latency


    【解决方案1】:

    这可能与 Android 的存储访问细节有关:

    手机上磁盘的背景等等,点击磁盘有什么问题 磁盘? Android 设备都在运行闪存,对吧?这就像 没有移动部件的超快 SSD?我不应该关心吗? 不幸的是,你这样做了。

    您不能依赖大多数使用的闪存组件或文件系统 Android 设备始终保持快速。使用的 YAFFS 文件系统 例如,许多 Android 设备对其所有设备都有全局锁定 操作。只有一个磁盘操作可以在整个过程中进行 设备。即使是简单的“统计”操作也可能需要相当长的时间,如果你 不走运。其他更传统的基于块设备的设备 当块旋转层时,文件系统仍然偶尔会受到影响 决定进行垃圾收集并进行一些缓慢的内部闪存擦除 操作。 (对于一些好的极客背景阅读,请参阅 lwn.net/Articles/353411)

    结论是移动设备上的“磁盘”(或文件系统)是 通常很快,但 90% 的延迟通常很差。 此外,大多数文件系统在变得更满时会减慢很多。 (请参阅 Google I/O Zippy Android 应用演讲中的幻灯片,链接已关闭 code.google.com/p/zippy-android)

    http://android-developers.blogspot.com/2010/12/new-gingerbread-api-strictmode.html

    【讨论】:

    • 这不会只涵盖在真机上运行的场景吗?我在模拟器上执行此操作,而我的笔记本电脑只有一个普通硬盘。
    • 也许是垃圾收集?您正在创建相当多的对象,而 GC 可能会占用一些 CPU 时间,这在模拟器上很昂贵。检查 logcat,它应该包含有关 GC 的信息。如果不是这种情况,请在“标准”VM 上运行测试并比较结果 - 可能是您的笔记本电脑的 FS/OS 问题。
    • 既然使用了java nanotime,难道是问题的原因?
    • GC 怎么样?你检查了吗?
    • 是的,我已经检查过 GC 是否是原因,但似乎并非如此,因为在没有运行的情况下会出现峰值。
    猜你喜欢
    • 2019-02-22
    • 1970-01-01
    • 2018-08-22
    • 2016-05-20
    • 2016-10-13
    • 2019-09-08
    • 2021-05-24
    • 1970-01-01
    • 2016-05-10
    相关资源
    最近更新 更多