为什么c比python快_为什么在C+中从stdin读取行的速度比Python慢得多?

本文讨论了在进行程序基准测试时如何正确使用`time`命令,指出使用`cat`结合管道可能引入的误差。建议直接将大文件作为输入传递给基准程序,以避免`cat`带来的额外开销。同时,文中通过实例展示了`cat`在不同测试结构中的性能影响,并强调在现代多核系统中,`cat`可能导致CPU使用率的误解。正确的基准测试应排除不必要的中间步骤,以确保测量的是目标程序的真实性能。
摘要由CSDN通过智能技术生成

我落后了几年,但是:

在原始文章的“编辑4/5/6”中,您使用的是结构:$ /usr/bin/time cat big_file | program_to_benchmark

这在几个不同的方面是错误的:你实际上是在计时“猫”的执行,而不是你的基准。“time”显示的‘user’和‘sys’CPU使用率是‘cat’,而不是您的基准程序。更糟糕的是,“真实”时间也不一定准确。根据‘cat’和本地操作系统中管道的实现,‘cat’可能会写入最后一个巨大缓冲区,并在读者进程完成工作之前就退出。

使用‘cat’是不必要的,实际上适得其反;你在添加移动部件。如果您使用的是一个足够老的系统(即使用单个CPU,并且-在某些代计算机中-I/O比CPU快)-仅仅是`cat‘正在运行这一事实就会严重影响结果。您还受输入和输出缓冲以及其他“cat”处理可能做的任何操作的限制。(这可能会给你带来一个“猫的无用途”如果我是兰德尔·施瓦茨。

一个更好的结构是:$ /usr/bin/time program_to_benchmark < big_file

在这个声明中,它是壳它打开bigfile,将其作为已经打开的文件描述符传递给您的程序(实际上是“time”,然后作为子进程执行您的程序)。100%的文件读取严格来说是你想要测试的程序的责任。这可以让您真正地阅读它的性能,而不会出现虚假的复杂情况。

我将提到两个可能但实际上是错误的,也可以考虑的“修正”(但我对它们的“编号”不同,因为在最初的文章中,这些都不是错误的):

答:你只需计时你的程序就可以“修复”这个问题:$ cat big_file | /usr/bin/time program_to_benchmark

B.或根据整个管道的时间安排:$ /usr/bin/time sh -c 'cat big_file | program_to_benchmark'

这些错误的原因与#2相同:它们仍然不必要地使用“cat”。我提到它们有几个原因:对于那些对POSIX外壳的I/O重定向设施不太满意的人来说,它们更“自然”。

在某些情况下,“猫”是需要(例如:要读取的文件需要某种访问权限,并且您不希望将该权限授予要对其进行基准测试的程序:‘sudo cat/dev/sda区/usr/bin/time my_press_test-no-output’)

在实践中,在现代机器上,在管道中添加的‘cat’可能没有什么实际意义。

但我说的最后一件事有点犹豫。如果我们检查“编辑5”的最后结果-$ /usr/bin/time cat temp_big_file | wc -l0.01user 1.34system 0:01.83elapsed 74%CPU ...

-这声称“cat”在测试期间消耗了74%的CPU;实际上1.34/1.83约占74%。也许是一连串的:$ /usr/bin/time wc -l < temp_big_file

剩下的0.49秒就好了!可能不会:这里的`cat‘必须支付从’disk‘(实际上是缓冲区缓存)传输文件的read()系统调用(或等效的),以及管道写入以将它们传递给’wc‘。正确的测试仍然需要执行这些read()调用;只有写到管道和从管道读取的调用才会被保存,而且这些调用应该相当便宜。

不过,我预计您将能够测量“Cat file x WC-l”和“wc-l

实际上,我在Linux 3.13(Ubuntu14.04)系统上对1.5G垃圾文件做了一些快速测试,获得了以下结果(这些结果实际上是“3中最好的”结果;当然,在启动缓存之后):$ time wc -l < /tmp/junk

real 0.280s user 0.156s sys 0.124s (total cpu 0.280s)$ time cat /tmp/junk | wc -l

real 0.407s user 0.157s sys 0.618s (total cpu 0.775s)$ time sh -c 'cat /tmp/junk | wc -l'real 0.411s user 0.118s sys 0.660s (total cpu 0.778s)

请注意,这两个管道结果声称占用的CPU时间(用户+sys)比实时时间要多。这是因为我使用的是shell(Bash)内置的‘time’命令,它知道管道;我在一台多核机器上,管道中的单独进程可以使用不同的内核,积累CPU时间比实时快。使用/usr/bin/time,我看到的CPU时间比实时的要小-表明它只能对命令行上传递给它的单个管道元素进行计时。另外,shell的输出给出毫秒,而/usr/bin/time只给出百分之一秒。

因此,在“wc-l”的效率级别上,“cat”产生了巨大的差异:409/283=1.453或45.3%的实时,775/280=2.768,或高达177%的使用CPU!在我的随机测试箱里。

我应该补充一点,在这些测试风格之间至少还有一个显著的区别,我不能说它是有利的还是错误的;你必须自己决定:

当您运行`Cat bix_file\/usr/bin/time my_Programm‘时,您的程序正在接收来自管道的输入,其速度与“cat”所发送的速度正好相同,并且以不大于“cat”编写的块的方式进行。

当您运行`/usr/bin/timemy_Program

当然,如果相同的程序在两种情况下的执行情况明显不同,这将是一个有趣的基准结果。它表明,实际上,程序或其I/O库是做一些有趣的事情,比如使用mmap()。因此,在实践中,最好是以两种方式来运行基准;也许可以用一些小因素来“原谅”运行`cat‘本身的成本,从而将`cat’结果打折扣。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值