2016-10-29 42 views
3

Q极其缓慢的输入/输出:是否可以在OS X,以改善此代码LLVM锵的IO:LLVM锵产生在OS X

test_io.cpp:

#include <iostream> 
#include <string> 

constexpr int SIZE = 1000*1000; 

int main(int argc, const char * argv[]) { 
    std::ios_base::sync_with_stdio(false); 
    std::cin.tie(nullptr); 

    std::string command(argv[1]); 
    if (command == "gen") { 
    for (int i = 0; i < SIZE; ++i) { 
     std::cout << 1000*1000*1000 << " "; 
    } 
    } else if (command == "read") { 
    int x; 
    for (int i = 0; i < SIZE; ++i) { 
     std::cin >> x; 
    } 
    } 
} 

编译:

clang++ -x c++ -lstdc++ -std=c++11 -O2 test_io.cpp -o test_io 

基准:

> time ./test_io gen | ./test_io read 

real 0m2.961s 
user 0m3.675s 
sys  0m0.012s 

除了可悲的事实,10MB的文件阅读成本3秒,这是除G慢 ++(通过自制安装):

> gcc-6 -x c++ -lstdc++ -std=c++11 -O2 test_io.cpp -o test_io 
> time ./test_io gen | ./test_io read 

real 0m0.149s 
user 0m0.167s 
sys  0m0.040s 

我铛版本是Apple LLVM version 7.0.0 (clang-700.0.72)。从自制软件(3.7和3.8)安装的clang也会产生缓慢的io。安装在Ubuntu(3.8)上的clang生成快速io。 Apple LLVM version 8.0.0生成缓慢的IO(2人问)。

我也dtrussed有点(sudo dtruss -c "./test_io gen | ./test_io read"),发现铛版本使得2686个write_nocancel系统调用,而gcc版本使得2079个writev系统调用。这可能指向问题的根源。

+0

相关http://stackoverflow.com/questions/38624468/clang-fstreams-10x-slower- than-g – Danh

+0

您是否尝试过-O3 – Danh

+0

如果您将来自clang编译版本的输出提供给gcc编译版本,它仍然非常快,但是如果将gcc编译版本提供给clang编译版本,它会变慢 - 所以我推断它是铿锵声慢的读数。如果您将从空间输出的字符更改为“X”,则它们都快并且速度相同。 –

回答

3

问题出在libC++中,它没有实现sync_with_stdio。

您的命令行clang++ -x c++ -lstdc++ -std=c++11 -O2 test_io.cpp -o test_io不使用libstdC++,它将使用libC++。要强制使用libstdC++,您需要-stdlib=libstdc++

小例子,如果你输入的文件准备:

int main(int argc, const char * argv[]) { 
    std::ios_base::sync_with_stdio(false); 
    int x; 
    for (int i = 0; i < SIZE; ++i) { 
     std::cin >> x; 
    } 
} 

时序:

$ clang++ test_io.cpp -o test -O2 -std=c++11 
$ time ./test read < input 
real 0m2.802s 
user 0m2.780s 
sys 0m0.015s 
$ clang++ test_io.cpp -o test -O2 -std=c++11 -stdlib=libstdc++ 
clang: warning: libstdc++ is deprecated; move to libc++ 
$ time ./test read < input 
real 0m0.185s 
user 0m0.169s 
sys 0m0.012s 
+0

sync_with_stdio的lib ++实现位于[src/ios.cpp](http://llvm.org/svn/llvm-project/libcxx/trunk/src/ios.cpp)的末尾。正如Joky所说的那样,这是一个无用的工具。 –