登录Python时使用funcName会对性能产生任何影响吗?

时间:2011-11-24 08:56:25

标签: python performance logging

只是在Python中查看日志记录文档,并将funcName作为日志格式化程序中的参数。

虽然它看起来很方便,很明显可以很好地查看日志来自哪里,有人提出了对它的担忧,可能需要生成一个性能损失的堆栈跟踪。

我认为它使用类似sys._getframe()的东西而不是inspect模块,这会对性能产生影响。

我们可以在生产环境中使用funcName,还是应该远离?

2 个答案:

答案 0 :(得分:4)

抵制猜测的诱惑,作为Python发行版的一部分,您可以使用日志记录源。

如何找到函数名称(logging/__init__.py):

#
# _srcfile is used when walking the stack to check when we've got the first
# caller stack frame.
#
if hasattr(sys, 'frozen'): #support for py2exe
    _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:])
elif __file__[-4:].lower() in ['.pyc', '.pyo']:
    _srcfile = __file__[:-4] + '.py'
else:
    _srcfile = __file__
_srcfile = os.path.normcase(_srcfile)

# next bit filched from 1.5.2's inspect.py
def currentframe():
    """Return the frame object for the caller's stack frame."""
    try:
        raise Exception
    except:
        return sys.exc_info()[2].tb_frame.f_back

if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3)
# done filching

然后再说:

def findCaller(self):
    """
    Find the stack frame of the caller so that we can note the source
    file name, line number and function name.
    """
    f = currentframe()
    #On some versions of IronPython, currentframe() returns None if
    #IronPython isn't run with -X:Frames.
    if f is not None:
        f = f.f_back
    rv = "(unknown file)", 0, "(unknown function)"
    while hasattr(f, "f_code"):
        co = f.f_code
        filename = os.path.normcase(co.co_filename)
        if filename == _srcfile:
            f = f.f_back
            continue
        rv = (filename, f.f_lineno, co.co_name)
        break
    return rv

另外,无需担心开销:它会在计算之前计算出函数名称,无论你是否需要它,所以你也可以使用它。

答案 1 :(得分:1)

这是一个测试应用程序,显示将文件名和行号写入文件在本地计算机上花费大约1秒/ 500000个请求。

#!/usr/bin/env python

import traceback, sys, time

def writeinfo(f, on=True):

    # give the function something to do
    s=sum(range(1000))

    if on:
        fr = sys._getframe(1)
        s = "%s (line %s) " % (fr.f_code.co_filename, fr.f_lineno)
        f.write(s)

cnt = 50000

t1 = time.time()

f = open('tempfile.log','w')

for i in range(cnt):
    writeinfo(f)

f.close()

t2 = time.time()

for i in range(cnt):
    writeinfo(f, on=False)

t3 = time.time()

print "Test time with    file write: %s" % (t2-t1) 
print "Test time without file write: %s" % (t3-t2) 

结果:

Test time with    file write: 1.17307782173
Test time without file write: 1.08166718483