V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
whx20202
V2EX  ›  Python

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

  •  
  •   whx20202 · Feb 4, 2017 · 16207 views
    This topic created in 3370 days ago, the information mentioned may be changed or developed.

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

    不知道 python 是不是也一样的

    34 replies    2021-01-26 10:34:13 +08:00
    virusdefender
        1
    virusdefender  
       Feb 4, 2017 via iPhone
    io 会影响性能的,但是使用 log 是为了更方便管理吧。。
    whx20202
        2
    whx20202  
    OP
       Feb 4, 2017
    我就怕 println 是同步阻塞 而且没有缓存,来一个请求发一次
    ryd994
        3
    ryd994  
       Feb 4, 2017 via Android
    缓存是不可能的
    有缓冲
    techmoe
        4
    techmoe  
       Feb 4, 2017 via Android
    print 好像是会同步阻塞的吧
    感觉最能体现这一点的应该在网络延时高的情况下 ssh 进服务器跑 py 的时候,由于输出耗时长所以带大量 print 的方法的执行速度肯定会拖累下来
    whx20202
        5
    whx20202  
    OP
       Feb 4, 2017
    @ryd994 我想的应该就是缓冲 尴尬。。
    chy373180
        6
    chy373180  
       Feb 4, 2017
    会的
    misaka19000
        7
    misaka19000  
       Feb 4, 2017 via Android
    io 本来速度就很慢,但是请问下使用 log 会比直接 print 快吗难道?
    robinlovemaggie
        8
    robinlovemaggie  
       Feb 4, 2017
    @misaka19000 看你用哪种了,如果把 log 放到 redis 里用 pub,sub 来实现会好很多。
    Neveroldmilk
        9
    Neveroldmilk  
       Feb 4, 2017
    当然会,所以不到关键时刻,不要随便 print ,虽然 print 性能下降到原来几分之一很正常。
    knktc
        10
    knktc  
       Feb 4, 2017
    会严重影响性能~
    simple2025
        11
    simple2025  
       Feb 4, 2017
    如果并发高,logger 就少点咯,然而我没有并发
    D3EP
        12
    D3EP  
       Feb 4, 2017 via Android
    @misaka19000 log 框架有异步的,减少 IO 次数,提高效率
    est
        13
    est  
       Feb 4, 2017
    >/dev/null 就不会太影响性能。
    slixurd
        14
    slixurd  
       Feb 4, 2017   ❤️ 1
    不懂 Python,不过原理差不多吧
    虽然 print 和 logger 都一样是 io consume 的,不过很多 logger 是基于 ringbuffer 做的异步输出
    另外还有线程安全的问题,Python 的 print 也是线程不安全的,你有加锁么......
    另外如果用 print,你要把日志打印到文件,如果没有用第三方 log rotate 工具,日志会堆积...
    堆积到磁盘满了,你想删除日志文件,还要等所有持有 inode 的进程都停掉文件才能被删除,不停止进程还没法清空磁盘
    lbp0200
        15
    lbp0200  
       Feb 4, 2017 via Android   ❤️ 1
    首先,你要有这样一个高并发的程序。
    misaka19000
        16
    misaka19000  
       Feb 4, 2017
    @D3EP 本质上应该还是把数组先保存在内存,之后在写入到磁盘吧?
    lbp0200
        17
    lbp0200  
       Feb 4, 2017
    @misaka19000 不能这样,会有内存溢出的风险
    ke1e
        18
    ke1e  
       Feb 4, 2017 via Android
    两个耗时应该一样吧,如果是高并发,肯定 logger 好
    misaka19000
        19
    misaka19000  
       Feb 4, 2017
    @lbp0200 为什么你的回复没有提醒?
    guyskk
        20
    guyskk  
       Feb 4, 2017 via Android
    log 有不同级别,可以关闭,可以替换内部实现, print 就很难拓展了
    liuzhiyong
        21
    liuzhiyong  
       Feb 4, 2017
    我觉得“大量使用 print ”会影响性能。因为“ print ”本来就是慢的(属于 IO ),我*猜测*它比写文件还要慢,所以会拖慢速度。
    vincenttone
        22
    vincenttone  
       Feb 4, 2017   ❤️ 1
    ……
    print 是往标准输出写数据,在 python 上应该是有缓冲
    写日志一般调用的也是有缓冲的方法,同时写日志模块自己也会设计缓冲
    你可以都理解成写文件
    但是你都往一个文件里写的时候,并发高到阻塞就成为一个问题。
    标准输出只有一个,文件可以有很多,但是磁盘的读写速度也是有限的。
    ——————————————
    所以,你要考虑你程序的性质
    一个简单的展示用 print 没什么问题
    如果输出太快你看不过来,可能那时候还没触及你所谓的性能瓶颈,可能那时候瓶颈是人眼
    如果你的程序是高并发程序,即使不触及瓶颈,你能保证看到所有你想要的输出吗?能保证以后查找问题的时候使用吗?
    billion
        23
    billion  
       Feb 4, 2017   ❤️ 2
    这么给你说吧:
    ```python
    a = 2**999999999999
    ```
    这一行代码不到一秒钟就可以计算完毕。
    但是如果你加上一行
    print(a)

    那么你需要等几个小时才能看到有东西显示出来。
    ovear
        24
    ovear  
       Feb 4, 2017
    io 流很影响性能、、、
    D3EP
        25
    D3EP  
       Feb 4, 2017
    @misaka19000 对。一般放到队列里。
    misaka19000
        26
    misaka19000  
       Feb 4, 2017
    @billion 等了十分钟也没计算完毕。。。
    IanPeverell
        27
    IanPeverell  
       Feb 4, 2017
    不能推荐大量使用的原因之一是非线程安全的
    tkisme
        28
    tkisme  
       Feb 4, 2017
    @misaka19000
    a = 2**9999999
    jininij
        29
    jininij  
       Feb 4, 2017   ❤️ 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 更好的方案。
    yuchting
        30
    yuchting  
       Feb 4, 2017 via Android
    我的第一印象也是 py 这种单线程优先的语言, print 绝对会影响性能的吧?
    linbiaye
        31
    linbiaye  
       Feb 4, 2017
    print 多了是一定会的, print 使用的是字符设备, io 中最慢的一款。
    kingddc314
        32
    kingddc314  
       Feb 4, 2017 via Android
    单论写效率问题,一个是标准输出 1 ,一个是写文件,如果缓冲方式一样,效率是差别不大的。之所以建议 logger 而不是 print ,应该是方便日志管理,设置日志输出级别,多线程日志输出同步,以及玩异步写什么的。
    ryd994
        33
    ryd994  
       Feb 4, 2017   ❤️ 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 也会
    DF5206A
        34
    DF5206A  
       Jan 26, 2021
    影响比较大,我做处理一条一条文本记录的,读文本文件一行一条记录处理一下这样子
    如果每一行处理结果都打印,整个程序可能要慢三分之一到一半的样子
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   970 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 80ms · UTC 20:41 · PVG 04:41 · LAX 13:41 · JFK 16:41
    ♥ Do have faith in what you're doing.