有的 Java 编程规范禁止使用 print 强制让用 logger 代替
不知道 python 是不是也一样的
1
virusdefender 2017-02-04 09:27:06 +08:00 via iPhone
io 会影响性能的,但是使用 log 是为了更方便管理吧。。
|
2
whx20202 OP 我就怕 println 是同步阻塞 而且没有缓存,来一个请求发一次
|
3
ryd994 2017-02-04 09:40:37 +08:00 via Android
缓存是不可能的
有缓冲 |
4
techmoe 2017-02-04 09:43:38 +08:00 via Android
print 好像是会同步阻塞的吧
感觉最能体现这一点的应该在网络延时高的情况下 ssh 进服务器跑 py 的时候,由于输出耗时长所以带大量 print 的方法的执行速度肯定会拖累下来 |
6
chy373180 2017-02-04 09:45:07 +08:00
会的
|
7
misaka19000 2017-02-04 09:46:13 +08:00 via Android
io 本来速度就很慢,但是请问下使用 log 会比直接 print 快吗难道?
|
8
robinlovemaggie 2017-02-04 09:49:08 +08:00
@misaka19000 看你用哪种了,如果把 log 放到 redis 里用 pub,sub 来实现会好很多。
|
9
Neveroldmilk 2017-02-04 09:56:13 +08:00
当然会,所以不到关键时刻,不要随便 print ,虽然 print 性能下降到原来几分之一很正常。
|
10
knktc 2017-02-04 10:03:27 +08:00
会严重影响性能~
|
11
chenqh 2017-02-04 10:28:36 +08:00
如果并发高,logger 就少点咯,然而我没有并发
|
12
D3EP 2017-02-04 10:37:24 +08:00 via Android
@misaka19000 log 框架有异步的,减少 IO 次数,提高效率
|
13
est 2017-02-04 10:38:57 +08:00
>/dev/null 就不会太影响性能。
|
14
slixurd 2017-02-04 10:42:25 +08:00 1
不懂 Python,不过原理差不多吧
虽然 print 和 logger 都一样是 io consume 的,不过很多 logger 是基于 ringbuffer 做的异步输出 另外还有线程安全的问题,Python 的 print 也是线程不安全的,你有加锁么...... 另外如果用 print,你要把日志打印到文件,如果没有用第三方 log rotate 工具,日志会堆积... 堆积到磁盘满了,你想删除日志文件,还要等所有持有 inode 的进程都停掉文件才能被删除,不停止进程还没法清空磁盘 |
15
lbp0200 2017-02-04 10:45:30 +08:00 via Android 1
首先,你要有这样一个高并发的程序。
|
16
misaka19000 2017-02-04 10:49:16 +08:00
@D3EP 本质上应该还是把数组先保存在内存,之后在写入到磁盘吧?
|
17
lbp0200 2017-02-04 10:59:28 +08:00
@misaka19000 不能这样,会有内存溢出的风险
|
18
ke1e 2017-02-04 11:02:05 +08:00 via Android
两个耗时应该一样吧,如果是高并发,肯定 logger 好
|
19
misaka19000 2017-02-04 11:08:04 +08:00
@lbp0200 为什么你的回复没有提醒?
|
20
guyskk 2017-02-04 11:14:59 +08:00 via Android
log 有不同级别,可以关闭,可以替换内部实现, print 就很难拓展了
|
21
liuzhiyong 2017-02-04 11:40:36 +08:00
我觉得“大量使用 print ”会影响性能。因为“ print ”本来就是慢的(属于 IO ),我*猜测*它比写文件还要慢,所以会拖慢速度。
|
22
vincenttone 2017-02-04 12:04:11 +08:00 1
……
print 是往标准输出写数据,在 python 上应该是有缓冲 写日志一般调用的也是有缓冲的方法,同时写日志模块自己也会设计缓冲 你可以都理解成写文件 但是你都往一个文件里写的时候,并发高到阻塞就成为一个问题。 标准输出只有一个,文件可以有很多,但是磁盘的读写速度也是有限的。 —————————————— 所以,你要考虑你程序的性质 一个简单的展示用 print 没什么问题 如果输出太快你看不过来,可能那时候还没触及你所谓的性能瓶颈,可能那时候瓶颈是人眼 如果你的程序是高并发程序,即使不触及瓶颈,你能保证看到所有你想要的输出吗?能保证以后查找问题的时候使用吗? |
23
billion 2017-02-04 12:19:21 +08:00 2
这么给你说吧:
```python a = 2**999999999999 ``` 这一行代码不到一秒钟就可以计算完毕。 但是如果你加上一行 print(a) 那么你需要等几个小时才能看到有东西显示出来。 |
24
ovear 2017-02-04 12:20:34 +08:00
io 流很影响性能、、、
|
25
D3EP 2017-02-04 12:52:14 +08:00
@misaka19000 对。一般放到队列里。
|
26
misaka19000 2017-02-04 13:24:56 +08:00
@billion 等了十分钟也没计算完毕。。。
|
27
IanPeverell 2017-02-04 13:45:23 +08:00
不能推荐大量使用的原因之一是非线程安全的
|
28
tkisme 2017-02-04 14:22:36 +08:00
@misaka19000
a = 2**9999999 |
29
jininij 2017-02-04 15:22:03 +08:00 1
我来说一个我前一段时间遇到的迷之 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 更好的方案。 |
30
yuchting 2017-02-04 16:08:40 +08:00 via Android
我的第一印象也是 py 这种单线程优先的语言, print 绝对会影响性能的吧?
|
31
linbiaye 2017-02-04 18:01:44 +08:00
print 多了是一定会的, print 使用的是字符设备, io 中最慢的一款。
|
32
kingddc314 2017-02-04 21:17:11 +08:00 via Android
单论写效率问题,一个是标准输出 1 ,一个是写文件,如果缓冲方式一样,效率是差别不大的。之所以建议 logger 而不是 print ,应该是方便日志管理,设置日志输出级别,多线程日志输出同步,以及玩异步写什么的。
|
33
ryd994 2017-02-04 23:26:19 +08:00 3
不见得会有很大性能影响:
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 也会 |
34
DF5206A 2021-01-26 10:34:13 +08:00
影响比较大,我做处理一条一条文本记录的,读文本文件一行一条记录处理一下这样子
如果每一行处理结果都打印,整个程序可能要慢三分之一到一半的样子 |