V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
t123yh
V2EX  ›  程序员

同样一段代码( C++ fstream 读 / 写 9000000 个数字),在不同环境下为何差异那么大?

  •  
  •   t123yh ·
    t123yh · 2016-08-11 12:55:13 +08:00 · 3627 次点击
    这是一个创建于 3017 天前的主题,其中的信息可能已经有所发展或是发生改变。

    以下是测试代码:

    #include <iostream>
    #include <vector>
    #include <fstream>
    
    using namespace std;
    
    int main(int argc, char **argv)
    {
    	if (argc != 2)
    	{
    		cout << "syntax: benchmark <option>" << endl << "option can be r or w" << endl;
    		cout << "argc: " << argc << endl;
    		return 1;
    	}
    	const int count = 9000000;
    	vector<int> data(count);
    	if (argv[1][0] == 'w')
    	{
    		ofstream fout("test.txt");
    		for (int i = 0; i < count; i++)
    		{
    			fout << i << " ";
    		}
    	}
    	else if (argv[1][0] == 'r')
    	{
    		ifstream fin("test.txt");
    		for (int i = 0; i < count; i++)
    		{
    			fin >> data[i];
    		}
    	}
    }
    

    这段代码会自动生成 test.txt ,其中是 0 - 8999999 这 9000000 个数字。 测试结果 注: Windows 上使用 ptime( http://www.pc-tools.net/win32/ptime/) 测试运行时间; Linux 取 time 命令返回的 real 值。 不同环境下,差异为何如此之大?特别是 Ubuntu 和 WSL ,用的 binary 都是一样的( WSL 上编译,然后复制到 Ubuntu )如何减小 Ubuntu 上运行时间?

    16 条回复    2016-08-13 10:01:10 +08:00
    exch4nge
        1
    exch4nge  
       2016-08-11 13:31:09 +08:00
    没明白楼主这测试意义何在……这段代码运行时间主要跟以下几个东西有关
    0. 硬件( CPU ,磁盘)
    1. 编译器。 crt 实现,编译优化程度。
    2. 文件系统
    3. 同 OS 中的其它进程
    等等……

    Ubuntu 和 WSL 的 binary 一样,但貌似硬件不一样吧
    t123yh
        2
    t123yh  
    OP
       2016-08-11 14:29:58 +08:00 via Android
    @exch4nge 但 WSL 和 Windows 差距不应如此之大啊,主要是如何优化
    arakashic
        3
    arakashic  
       2016-08-11 14:49:03 +08:00
    LZ 你这测试方法就有问题,你测试的是程序整体的执行时间,影响因素太多了。你至少应该把不同部分的执行时间测一下,然后再分析为什么。
    just4test
        4
    just4test  
       2016-08-11 14:54:20 +08:00
    i7 和赛扬能一样吗?这不是废话。
    磁盘有写入缓存,你这数据量太少不会充满写入缓存,因此所有磁盘都可以认为是 randisk 。
    然后瓶颈就是内存频率 /带宽和 cpu 了。
    exch4nge
        5
    exch4nge  
       2016-08-11 15:21:05 +08:00
    @t123yh 我这边没有 WSL ,没法具体测。另外一个主要占用 CPU 的是 stream 的<<与>>,尤其用 MS 的 CRT 的时候,这部分转换比较耗时。

    C++的 iostream 遭人唾弃是有原因的,一般都不会用于高频读写。

    WSL 和 Windows 差距主要来源于编译器与 CRT 库不一样。

    另外 VS2015 默认创建的 C++工程,默认启用了很多编译选项,包括很多检查,这部分也耗费了一些时间。
    klausroot
        6
    klausroot  
       2016-08-11 15:21:45 +08:00
    linux 下的是 ext 文件系统, windows 下的 fat32 或 ntfs ,相比之下 ext 的更高效
    t123yh
        7
    t123yh  
    OP
       2016-08-11 16:25:37 +08:00 via Android
    @klausroot WSL 也是在 NTFS 上跑的
    whatot
        8
    whatot  
       2016-08-11 16:48:40 +08:00
    archlinux g++ 6.1.1 -O2 ext4

    CT480BX200SSD1 写入 0.47s ,读取 0.55s
    SM951 写入 0.46s ,读取 0.55s
    FrankHB
        9
    FrankHB  
       2016-08-11 17:44:29 +08:00
    没 sync_with_stdio(false)纠结啥性能……是想看 cstdio (无误)实现得有多蠢么……
    FrankHB
        10
    FrankHB  
       2016-08-11 17:48:49 +08:00
    @FrankHB 好吧,文件流……以上作废。首先 Debug 没啥可比性就不用管了(调_ITERATOR_DEBUG_LEVEL 和_GLIBCXX_DEBUG 也不能指望半径八两)。然后……噫,这些环境的外部变量太多,还是没啥可比性啊……
    FrankHB
        11
    FrankHB  
       2016-08-11 17:52:57 +08:00
    比较能直接比较的 WSL 的差距,猜测是 M$自知 NTFS 太笨重所以在 WSL 实现文件系统驱动塞了些特技,调缓存之类。
    嗯, Naive Windows ……
    yonka
        12
    yonka  
       2016-08-11 18:18:24 +08:00
    @FrankHB 活捉帝球
    Neveroldmilk
        13
    Neveroldmilk  
       2016-08-11 18:46:11 +08:00
    VS2015 的 Debug 模式是不是开了什么性能检测的额外功能了。另外,不同 C 编译器的性能和分区类型不一样也会导致性能差异。
    t123yh
        14
    t123yh  
    OP
       2016-08-11 23:44:55 +08:00 via Android
    @FrankHB 我用的 fstream ,和 cstdio 无关
    t123yh
        15
    t123yh  
    OP
       2016-08-11 23:46:39 +08:00 via Android
    好了,估计是 CPU 性能问题,我在 i7 的 Ubuntu 上跑出了 0.4s 的结果
    ragnaroks
        16
    ragnaroks  
       2016-08-13 10:01:10 +08:00
    说明 Windows 还是 Naive 啊
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1882 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 16:33 · PVG 00:33 · LAX 08:33 · JFK 11:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.