Python 中大量使用 print 会影响性能吗?

2017-02-04 09:23:58 +08:00
 whx20202

有的 Java 编程规范禁止使用 print 强制让用 logger 代替

不知道 python 是不是也一样的

15160 次点击
所在节点    Python
34 条回复
liuzhiyong
2017-02-04 11:40:36 +08:00
我觉得“大量使用 print ”会影响性能。因为“ print ”本来就是慢的(属于 IO ),我*猜测*它比写文件还要慢,所以会拖慢速度。
vincenttone
2017-02-04 12:04:11 +08:00
……
print 是往标准输出写数据,在 python 上应该是有缓冲
写日志一般调用的也是有缓冲的方法,同时写日志模块自己也会设计缓冲
你可以都理解成写文件
但是你都往一个文件里写的时候,并发高到阻塞就成为一个问题。
标准输出只有一个,文件可以有很多,但是磁盘的读写速度也是有限的。
——————————————
所以,你要考虑你程序的性质
一个简单的展示用 print 没什么问题
如果输出太快你看不过来,可能那时候还没触及你所谓的性能瓶颈,可能那时候瓶颈是人眼
如果你的程序是高并发程序,即使不触及瓶颈,你能保证看到所有你想要的输出吗?能保证以后查找问题的时候使用吗?
billion
2017-02-04 12:19:21 +08:00
这么给你说吧:
```python
a = 2**999999999999
```
这一行代码不到一秒钟就可以计算完毕。
但是如果你加上一行
print(a)

那么你需要等几个小时才能看到有东西显示出来。
ovear
2017-02-04 12:20:34 +08:00
io 流很影响性能、、、
D3EP
2017-02-04 12:52:14 +08:00
@misaka19000 对。一般放到队列里。
misaka19000
2017-02-04 13:24:56 +08:00
@billion 等了十分钟也没计算完毕。。。
IanPeverell
2017-02-04 13:45:23 +08:00
不能推荐大量使用的原因之一是非线程安全的
tkisme
2017-02-04 14:22:36 +08:00
@misaka19000
a = 2**9999999
jininij
2017-02-04 15:22:03 +08:00
我来说一个我前一段时间遇到的迷之 BUG 。
是一个 Django 的项目,还在开发阶段。之前一直在本地开发,那段时间把项目部署到测试服务器上。
我使用 django 自带的 web 服务器,用 `(manage.py runserver 0.0.0.0:8000 > /dev/null &)` 来执行。
我访问我本地的网站,一直都正常。但访问服务器上的网站,有一些特定的页面, HTTP 请求始终不会结束。表现为网页能打开,但浏览器的小圈圈一直不会停。使用 curl 请求,能立刻获得页面完整内容,但脚本必须要等到超时才能结束。使用 ajax 调用,因为 http response 一直不结束,所以 ajax 成功的回调也无法执行,直到 http 超时才能得到一个 timeout 的错误。
我整理了问题出现的各种条件,直到我发现,只要我不关终端,问题就不会出现,关闭了终端,问题才有可能出现。我这才恍然大悟。
> 只重定向输出,不会重定向错误信息。我的那个命令会将输出丢弃,但错误信息仍然会打印到我当前的终端上。我在本地时, run 是在 IDE 的 Terminal 中执行的,只要我 IDE 不关闭,这个会话其实一直都在运行。用`( ... &)`运行的命令是没有一个终端界面的, Django 中偶尔的错误信息和和 log 信息没有重定向也无法显示,会抛出到它的父终端来显示。当我关闭了 xshell 后,父会话结束了,这些输出没有任何人愿意认领,会堆积在输出缓存里,当输出缓存堆满,就被阻塞。 http 的结束符无法发送,前台浏览器就会阻塞。

跑题了。回到主题
不建议大量的 print 。在开发阶段,这些输出能够很好的帮助找到错误。但如果输出过多,则会干扰有用的信息。建议需要保留存档的使用专用的日志模块实现。调试则用 IDE 的 Debug run 。因为无论什么用途,都有比 print 更好的方案。
yuchting
2017-02-04 16:08:40 +08:00
我的第一印象也是 py 这种单线程优先的语言, print 绝对会影响性能的吧?
linbiaye
2017-02-04 18:01:44 +08:00
print 多了是一定会的, print 使用的是字符设备, io 中最慢的一款。
kingddc314
2017-02-04 21:17:11 +08:00
单论写效率问题,一个是标准输出 1 ,一个是写文件,如果缓冲方式一样,效率是差别不大的。之所以建议 logger 而不是 print ,应该是方便日志管理,设置日志输出级别,多线程日志输出同步,以及玩异步写什么的。
ryd994
2017-02-04 23:26:19 +08:00
不见得会有很大性能影响:
1. 真要高性能用 C ,或者 C 模块,别欺负 Python
2. 有 buffer ,而且写入 log 文件 buffer 比写终端要快,因为不是 linebuffer
推荐用 logging 是因为:
1. 不需要自己 format ,可以简单套模板
2. logging 会以行为单位,一次性写入,或者用锁。如果不这样的话多线程的 log 可能会撕裂
3. 尽管 logging 默认是写入文件,但是可以通过拓展 logger.emit(),轻松实现其他输出,比如输出到日志服务器。而 print 不可能扩展,也只能由外部程序捕捉输出文件再转发

说那么多有的没的,怎么不去看看 CPython 源码呢? https://hg.python.org/cpython/file/tip/Lib/logging/__init__.py

@techmoe stdio is line buffered ,方便用户程序,这是 Linux 和很多操作系用的默认

@liuzhiyong buffered IO 怎么会慢,进 buffer 就是一次 memory copy

@billion 那你用 logging 输出一下 2*999999 试试?

@jininij 用终端跑后台本来就是不对。说实话,我怀疑你关了终端你的后端已经被杀掉了。正经用 mod_wsgi 或者 gunicorn 根本没这档子事。正规用 systemd , systemd 会捕获所有输出,转给 journald

@yuchting GIL 不锁 IO

@linbiaye print 会的话 logging 也会
DF5206A
2021-01-26 10:34:13 +08:00
影响比较大,我做处理一条一条文本记录的,读文本文件一行一条记录处理一下这样子
如果每一行处理结果都打印,整个程序可能要慢三分之一到一半的样子

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/337970

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX