我有一个包含数千个数字的文件,每个数字都在自己的行上:

34
42
11
6
2
99
...

我想写一个脚本,它将打印文件中所有数字的总和。我有一个解决办法,但不是很有效。(运行需要几分钟。)我在寻找一个更有效的解决方案。有什么建议吗?


当前回答

考虑到你需要通读整个文件,我不知道你是否能找到比这更好的。

$sum = 0;
while(<>){
   $sum += $_;
}
print $sum;

其他回答

下面是一个使用python和生成器表达式的解决方案。在我破旧的笔记本电脑上测试了无数个数字。

time python -c "import sys; print sum((float(l) for l in sys.stdin))" < file

real    0m0.619s
user    0m0.512s
sys     0m0.028s
$ perl -MList::Util=sum -le 'print sum <>' nums.txt

对于这样的任务,我更喜欢使用GNU数据集,因为它比perl或awk更简洁易读。例如

datamash sum 1 < myfile

其中1表示数据的第一列。

GNU Parallel可以通过将工作负载分散到多个核心来改进上面的许多问题。

在下面的例子中,我们将500个数字的块(——max-lines=500)发送给bc进程,这些进程一次并行执行4个(-j 4)。然后,结果由最终的bc聚合。

time parallel --max-lines=500 -j 4 --pipe "paste -sd+ - | bc" < random_numbers | paste -sd+ - | bc

工作规模和并行过程数量的最佳选择取决于机器和问题。请注意,这种解决方案只有在存在大量并行流程且每个流程都有大量工作时才会真正发挥作用。

c++“俏皮话”:

#include <iostream>
#include <iterator>
#include <numeric>
using namespace std;

int main() {
    cout << accumulate(istream_iterator<int>(cin), istream_iterator<int>(), 0) << endl;
}