Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 这个cProfile结果告诉我需要修复什么?_Python_Performance_Profiling_Profile_Cprofile - Fatal编程技术网

Python 这个cProfile结果告诉我需要修复什么?

Python 这个cProfile结果告诉我需要修复什么?,python,performance,profiling,profile,cprofile,Python,Performance,Profiling,Profile,Cprofile,我想提高Python脚本的性能,并一直在使用cProfile生成性能报告: python -m cProfile -o chrX.prof ./bgchr.py ...args... 我用Python的pstats打开了这个chrX.prof文件,并打印出了统计数据: Python 2.7 (r27:82500, Oct 5 2010, 00:24:22) [GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2 Type "help", "cop

我想提高Python脚本的性能,并一直在使用
cProfile
生成性能报告:

python -m cProfile -o chrX.prof ./bgchr.py ...args...
我用Python的
pstats
打开了这个
chrX.prof
文件,并打印出了统计数据:

Python 2.7 (r27:82500, Oct  5 2010, 00:24:22) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pstats
>>> p = pstats.Stats('chrX.prof')
>>> p.sort_stats('name')
>>> p.print_stats()                                                                                                                                                                                                                        
Sun Oct 10 00:37:30 2010    chrX.prof                                                                                                                                                                                                      

         8760583 function calls in 13.780 CPU seconds                                                                                                                                                                                      

   Ordered by: function name                                                                                                                                                                                                               

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)                                                                                                                                                                    
        1    0.000    0.000    0.000    0.000 {_locale.setlocale}                                                                                                                                                                          
        1    1.128    1.128    1.128    1.128 {bz2.decompress}                                                                                                                                                                             
        1    0.002    0.002   13.780   13.780 {execfile}                                                                                                                                                                                   
  1750678    0.300    0.000    0.300    0.000 {len}                                                                                                                                                                                        
       48    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}                                                                                                                                                          
        1    0.000    0.000    0.000    0.000 {method 'close' of 'file' objects}                                                                                                                                                           
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}                                                                                                                                             
  1750676    0.496    0.000    0.496    0.000 {method 'join' of 'str' objects}                                                                                                                                                             
        1    0.007    0.007    0.007    0.007 {method 'read' of 'file' objects}                                                                                                                                                            
        1    0.000    0.000    0.000    0.000 {method 'readlines' of 'file' objects}                                                                                                                                                       
        1    0.034    0.034    0.034    0.034 {method 'rstrip' of 'str' objects}                                                                                                                                                           
       23    0.000    0.000    0.000    0.000 {method 'seek' of 'file' objects}                                                                                                                                                            
  1757785    1.230    0.000    1.230    0.000 {method 'split' of 'str' objects}                                                                                                                                                            
        1    0.000    0.000    0.000    0.000 {method 'startswith' of 'str' objects}                                                                                                                                                       
  1750676    0.872    0.000    0.872    0.000 {method 'write' of 'file' objects}                                                                                                                                                           
        1    0.007    0.007   13.778   13.778 ./bgchr:3(<module>)                                                                                                                                                                          
        1    0.000    0.000   13.780   13.780 <string>:1(<module>)                                                                                                                                                                         
        1    0.001    0.001    0.001    0.001 {open}                                                                                                                                                                                       
        1    0.000    0.000    0.000    0.000 {sys.exit}                                                                                                                                                                                   
        1    0.000    0.000    0.000    0.000 ./bgchr:36(checkCommandLineInputs)                                                                                                                                                           
        1    0.000    0.000    0.000    0.000 ./bgchr:27(checkInstallation)                                                                                                                                                                
        1    1.131    1.131   13.701   13.701 ./bgchr:97(extractData)                                                                                                                                                                      
        1    0.003    0.003    0.007    0.007 ./bgchr:55(extractMetadata)                                                                                                                                                                  
        1    0.064    0.064   13.771   13.771 ./bgchr:5(main)                                                                                                                                                                              
  1750677    8.504    0.000   11.196    0.000 ./bgchr:122(parseJarchLine)                                                                                                                                                                  
        1    0.000    0.000    0.000    0.000 ./bgchr:72(parseMetadata)                                                                                                                                                                    
        1    0.000    0.000    0.000    0.000 /home/areynolds/proj/tools/lib/python2.7/locale.py:517(setlocale) 
编辑

如果在
parseJarchLine()
的第一个条件中注释掉
sys.stdout.write
语句,则我的运行时间从10.2秒变为4.8秒:

# with first conditional's "sys.stdout.write" enabled
$ time ./bgchr chrX test.bjarch > /dev/null
real    0m10.186s                                                                                                                                                                                        
user    0m9.917s                                                                                                                                                                                         
sys 0m0.160s  

# after first conditional's "sys.stdout.write" is commented out                                                                                                                                                                                           
$ time ./bgchr chrX test.bjarch > /dev/null
real    0m4.808s                                                                                                                                                                                         
user    0m4.561s                                                                                                                                                                                         
sys 0m0.156s

在Python中编写stdout是否真的那么昂贵?

与可能的优化相关的条目是那些具有较高nCall和tottime值的条目
bgchr:4()
:1()
可能指的是模块主体的执行,与此处无关

显然,性能问题来自字符串处理。这或许应该减少。热点是
split
join
sys.stdout.write
<代码>bz2。解压缩似乎成本也很高

我建议您尝试以下方法:

  • 您的主要数据似乎由选项卡分隔的CSV值组成。如果CSV阅读器性能更好,请尝试
  • sys.stdout在每次写入换行符时都进行行缓冲和刷新。考虑写入具有较大缓冲区大小的文件。
  • 不要在写出元素之前连接它们,而是按顺序将它们写入输出文件。您也可以考虑使用CSV编写器。
  • 使用BZ2File对象并将其传递给CSV阅读器,而不是立即将数据解压缩为单个字符串
实际上解压数据的循环体似乎只被调用一次。也许您可以找到一种方法来避免调用
dataHandle.read(size)
,该调用会生成一个巨大的字符串,然后对该字符串进行解压缩,并直接使用file对象

附录:BZ2File可能不适用于您的情况,因为它需要一个filename参数。您需要的是一个具有集成读取限制的文件对象视图,类似于ZipExtFile,但使用BZ2Decompressor进行解压缩


这里我的主要观点是,您的代码应该进行更改,以对数据执行更迭代的处理,而不是将其作为一个整体进行拼凑,然后再将其拆分。

如果您的代码如Lie Ryan所述更模块化,则此输出将更有用。但是,您可以从输出中获取一些信息,只需查看源代码即可:

您正在进行许多Python中实际上不需要的比较。例如,而不是:

如果len(entryText)>0:

你可以写:

if entryText:

在Python中,空列表的计算结果为False。对于空字符串也是如此,您也可以在代码中对其进行测试,更改它也会使代码更简短、更可读,因此:

   for line in metadataLines:      
        if line == '':
            break
        else:
            metadataList.append(line)
您只需执行以下操作:

for line in metadataLines:
    if line:
       metadataList.append(line)

在组织和性能方面,此代码还存在一些其他问题。例如,将变量多次分配给同一事物,而不是只创建一次对象实例并对对象执行所有访问。这样做会减少赋值的数量,也会减少全局变量的数量。我不想听起来过于挑剔,但这段代码似乎并没有考虑到性能

ncalls
仅当将数字与其他计数(如文件中的字符数/字段数/行数)进行比较可能会出现严重异常时才相关<代码>tottime和
累计时间
才是真正重要的
cumtime
是在函数/方法中花费的时间,包括在其调用的函数/方法中花费的时间
tottime
是在函数/方法中花费的时间,不包括在其调用的函数/方法中花费的时间

我发现在
tottime
cumtime
上对统计数据进行排序很有帮助,而不是在
name

bgchar
肯定是指脚本的执行,并不无关,因为它占用了13.5秒中的8.9秒;这8.9秒不包括它调用的函数/方法中的时间!仔细阅读@Lie Ryan关于将脚本模块化为函数的内容,并实施他的建议。同样地,@jonesy说

之所以提到
string
,是因为您
导入string
并仅在一个位置使用它:
string.find(元素[0],'p')
。在输出的另一行中,您会注意到string.find只被调用了一次,因此在本次脚本运行中不会出现性能问题。但是:您可以在其他任何地方使用
str
方法
string
函数现在已被弃用,它们通过调用相应的
str
方法来实现。您最好编写
元素[0]。查找('p')==0
以获得准确但更快的等价物,并可能希望使用
元素[0]。使用('p')
开始,这会让读者不知道
==0
是否应该是
=-1

@Bernd Petersohn提到的四种方法仅占用13.541秒的总执行时间中的3.7秒。在过分担心这些之前,先将脚本模块化为函数,再次运行cProfile,然后按
tottime
对统计数据进行排序

修改脚本后的问题更新:

“”“问题:如何处理联接、拆分和写入操作,以减少它们对此脚本性能的明显影响?”

哈?这三个函数总共占用了13.8秒中的2.6秒。你的parseJarchLine函数占用了8.5秒(不包括它调用的函数/方法占用的时间。
assert(8.5>2.6)

贝尔恩德已经指出了你可能会考虑做些什么。
for line in metadataLines:
    if line:
       metadataList.append(line)
def parseJarchLine(chromosome, line):
    global pLength
    global lastEnd
    elements = line.split('\t')
    if len(elements) > 1:
        if lastEnd != "":
            start = long(lastEnd) + long(elements[0])
            # [1] start = lastEnd + long(elements[0])
            # [2] start = lastEnd + int(elements[0])
            lastEnd = long(start + pLength)
            # [1] lastEnd = start + pLength
            sys.stdout.write("%s\t%ld\t%ld\t%s\n" % (chromosome, start, lastEnd, '\t'.join(elements[1:])))
        else:
            lastEnd = long(elements[0]) + long(pLength)
            # [1] lastEnd = long(elements[0]) + pLength
            # [2] lastEnd = int(elements[0]) + pLength
            sys.stdout.write("%s\t%ld\t%ld\t%s\n" % (chromosome, long(elements[0]), lastEnd, '\t'.join(elements[1:])))
    else:
        if elements[0].startswith('p'):
            pLength = long(elements[0][1:])
            # [2] pLength = int(elements[0][1:])
        else:
            start = long(long(lastEnd) + long(elements[0]))
            # [1] start = lastEnd + long(elements[0])
            # [2] start = lastEnd + int(elements[0])
            lastEnd = long(start + pLength)
            # [1] lastEnd = start + pLength
            sys.stdout.write("%s\t%ld\t%ld\n" % (chromosome, start, lastEnd))               
    return
sys.stdout.write("%s\t%ld\t%ld\t%s\n" % (chromosome, start, lastEnd, '\t'.join(elements[1:])))
payload = "%s\t%ld\t%ld\t%s\n" % (chromosome, start, lastEnd, '\t'.join(elements[1:]))
sys.stdout.write(payload)
def parseJarchLine(chromosome, line):
    global pLength
    global lastEnd
    elements = line.split('\t', 1)
    if elements[0][0] == 'p':
        pLength = int(elements[0][1:])
        return
    start = lastEnd + int(elements[0])
    lastEnd = start + pLength
    sys.stdout.write("%s\t%ld\t%ld" % (chromosome, start, lastEnd))
    if elements[1:]:
        sys.stdout.write(elements[1])
    sys.stdout.write(\n)