我想使用命令行将一百万个随机整数从 .txt 加载到 vector 中:
program.exe < million-integers.txt
我下面的代码可以运行,但需要几秒钟才能运行。我可以做些什么来让它更快吗?我在 SO 上找到了一些解决方案,但它们似乎都依赖于对文件路径进行硬编码。我希望能够通过命令行传递文件名。
vector<int> data;
int input;
while (cin >> input)
{
data.push_back(input);
}
cout << "Data loaded." << endl;
(C++ 新手在 Win 8.1 上使用 Visual Studio)
编辑:在这种情况下,我知道可以进行一些改进,因为我有其他人的 .exe 可以在一秒钟内完成。
编辑:所有整数都在同一行。
最佳答案
运行时间:4.08 秒。什么?太慢了!
为什么会这样?
我做了分析。我使用的是一个非常不同的系统:OS X 10.8,带有 Clang,但我的程序也很慢,我怀疑这是出于同样的原因。以下是分析结果中的两行(很抱歉格式化):
Running Time Self Symbol Name
3389.0ms 79.3% 76.0 std::__1::num_get<char, std::__1::istreambuf_iterator<char, std::__1::char_traits<char> > >::do_get(std::__1::istreambuf_iterator<char, std::__1::char_traits<char> >, std::__1::istreambuf_iterator<char, std::__1::char_traits<char> >, std::__1::ios_base&, unsigned int&, long&) const
824.0ms 19.2% 8.0 std::__1::basic_istream<char, std::__1::char_traits<char> >::sentry::sentry(std::__1::basic_istream<char, std::__1::char_traits<char> >&, bool)
如您所见,这两个函数几乎占了执行时间的 98.5%。哇!当我向下钻取时,这些耗费大量时间的库函数调用的是什么?
-
flockfile()
-
funlockfile()
-
pthread_mutex_unlock()
因此,在我的系统上,std::cin
的实现与 C 的 <stdio.h>
一起工作函数,因此它们可以在同一个程序中使用,并且这些函数确保与其他线程同步。这是低效的。
没有代码使用
<stdio.h>
, 所以不需要同步。只有一个线程使用 stdin,因此锁定过多,尤其是如果您对每个字符读取锁定一次。真是太过分了。锁和系统调用相当快……但是如果你做类似 1000 万次锁和系统调用的事情呢?不再快了。
注意:是的,我运行的是 OS X,在 Windows 上实际功能会有所不同。而不是 flockfile()
和 pthread_mutex_unlock()
无论 Windows 版本是什么,您都会看到。
解决方案 #1
停止使用重定向。如果你使用 ifstream
,那么假定您会自行锁定。在我的系统上,这给出了 0.42 秒的运行时间——接近 10 倍。
解决方案 #2
将所有内容读入一个字符串,然后解析该字符串。这允许您继续使用重定向来读取文件。
解决方案 #3
在 std::cin
上禁用锁定.抱歉各位,我不知道该怎么做。有可能。
性能限制
我怀疑 ifstream
版本远未达到您计算机的性能极限。如果性能至关重要,我怀疑当您的程序仅受内存带宽限制时,您可以获得接近 2 或 3 毫秒的热缓存运行时间。
关于c++ - 有没有更快的方法使用命令行在 C++ 中加载文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23960160/