方法比功能慢得多? [英] Method much slower than function?

查看:78
本文介绍了方法比功能慢得多?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,


我在Feisty Ubuntu上运行Python 2.5。我遇到了一些代码,

在方法中比在函数中慢得多。


############ ##### START SOURCE #############

#函数


def readgenome(filehandle):

s =''''

for filehandle.xreadlines():

if''>''in line:

继续

s + = line.strip()

返回s


#班级中的方法

班级栏:

def readgenome(self,filehandle):

self.s =''''

对于filehandle.xreadlines()中的行:

如果''>''在行:

继续

self.s + = line .strip()


################# END SOURCE ############## br />
在20,000行文本文件上运行函数和方法时,我获得以下内容:


>&g t; cProfile.run(" bar.readgenome(open(''cb_foo''))")



20004 function拨打10.214 CPU秒钟


订购者:标准名称


ncalls tottime percall cumtime percall

文件名:lineno (功能)

1 0.000 0.000 10.214 10.214< string>:1(< module>)

1 10.205 10.205 10.214 10.214 reader.py:11(readgenome)

1 0.000 0.000 0.000 0.000 {方法''禁用'

''_ lsprof.Profiler''对象}

19999 0.009 0.000 0.009 0.000 {方法'''''''''''''''''''''$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ b''文件''对象}

1 0.000 0.000 0.000 0.000 {open}

< blockquote class =post_quotes >
>> cProfile.run(" z = r.readgenome(open(''cb_foo''))")



20004函数调用0.041 CPU秒


订购者:标准名称


ncalls tottime percall cumtime percall

文件名:lineno(函数)

1 0.000 0.000 0.041 0.041< string>:1(< module>)

1 0.035 0.035 0.041 0.041 reader.py:2(readgenome)

1 0.000 0.000 0.000 0.000 {方法''禁用''

''_ lsprof.Profiler''对象}

19999 0.007 0.000 0.007 0.000 {'''''''''''''''''''''''''''''$ $ $ $ $ $ $ $ $ $ $ $ $ 000 xreadlines''

''文件''对象}

1 0.000 0.000 0.000 0.000 {open}

该方法需要10秒钟,功能调用0.041秒!


Y. es,我知道我写的底层代码相当低效,而且我可以通过单个file.read()调用来简化它,如果一个

xreadlines()+带环。不过,性能上的差异是相当惊人的!有什么意见吗?


谢谢,


Iddo

解决方案

在2007-06-14, id****@gmail.com < id **** @ gmail.comwrote:


大家好,


我在Feisty Ubuntu上运行Python 2.5。我遇到了一些代码,

在方法中比在函数中慢得多。


############ ##### START SOURCE #############

#函数


def readgenome(filehandle):

s =''''

for filehandle.xreadlines():

if''>''in line:

继续

s + = line.strip()

返回s


#班级中的方法

班级栏:

def readgenome(self,filehandle):

self.s =''''

对于filehandle.xreadlines()中的行:

如果''>''在行:

继续

self.s + = line .strip()


################# END SOURCE ############## br />
在20,000行文本文件上运行函数和方法时,我获得以下内容:


>>> cProfile.run(" bar.readgenome(open(''cb_foo''))" )



在10.214 CPU秒内的20004函数调用


订购者:标准名称


ncalls tottime percall cumtime percall

文件名:lineno(函数)

1 0.000 0.000 10.214 10.214< string>:1(< module> )

1 10.205 10.205 10.214 10.214 reader.py:11(readgenome)

1 0.000 0.000 0.000 0.000 {方法''禁用''

''_lsprof.Profiler''对象}

19999 0.009 0.000 0.009 0.000 {方法''条带''''str''

对象}

1 0.000 0.000 0.000 0.000 {方法''xreadlines''

''文件''对象}

1 0.000 0.000 0.000 0.000 {open}


>>> cProfile.run(" z = r.readgenome (open(''cb_foo''))")



20004函数调用0.041 CPU秒


订购者:标准名称


ncalls tottime percall cumtime percall

文件名:lineno(功能)

1 0.000 0.000 0.041 0.041< string>:1(< module>)

1 0.035 0.035 0.041 0.041 reader.py:2(readgenome)

1 0.000 0.000 0.000 0.000 {method' 禁用

''_ lsprof.Profiler''对象}

19999 0.007 0.000 0.007 0.000 {方法''条带''''str''

对象}

1 0.000 0.000 0.000 0.000 {方法''xreadlines''

''文件''对象}

1 0.000 0.000 0.000 0.000 {open}


方法需要10秒,函数调用0.041秒!


是的,我知道我写了底层代码而不是
效率低下,而且我可以使用单个

file.read()来调用它,而不是xreadlines()+ strip循环。

不过,性能上的差异相当惊人!

有何评论?



重复的属性查找self.s,与非方法相比,'b
减慢了它的速度版本。


尝试以下简单优化,使用局部变量

而不是属性来构建结果。


#班级中的方法

班级栏:

def readgenome(self,filehandle):

s =''''

for filehandle.xreadlines():

如果''>''在行:

继续

s + = line.strip()

self.s = s


为了进一步加快速度,请考虑使用str.join成语

而不是str。+ =,并使用生成器表达式而不是

显式循环。


#类中的方法

班级栏:

def readgenome(self,filehandle):

self.s =''''。join(line.strip( )for filehandle)


-

N. eil Cerutti


En Wed,2007年6月13日21:40:12 -0300,< id **** @gmail.comescribió:


大家好,


我在Feisty Ubuntu上运行Python 2.5。我遇到了一些代码,

在方法中比在函数中慢得多。


############ ##### START SOURCE #############

#函数


def readgenome(filehandle):

s =''''

for filehandle.xreadlines():

if''>''in line:

继续

s + = line.strip()

返回s


#班级中的方法

班级栏:

def readgenome(self,filehandle):

self.s =''''

对于filehandle.xreadlines()中的行:

如果''>''在行:

继续

self.s + = line .strip()



在上面的函数中,s是一个局部变量,并且访问本地

变量是非常有效的(使用数组局部变量,

编译器为每个变量静态分配一个索引。

使用self.s,在ot上她的手,需要为每次访问进行名称查找。

最明显的变化是使用局部变量s,并且只分配

self.s = s结束。这应该使两种方法几乎相同

的性能。

此外,+ =对字符串来说效率相当低;通常的成语是

使用''''。join(items)

因为你有Python 2.5,你可以使用该文件作为它自己的迭代器;

结合所有这些:


返回''''。join(line.strip()用于文件句柄中的行,如果''>''不在行中)


-

Gabriel Genellina


2007-06-14,< a href =mailto:id **** @ gmail.com> id **** @ gmail.com < id **** @ gmail.comwrote:


该方法需要10秒,函数调用0.041秒!



当你以其他顺序运行它们会发生什么?


第一次读取文件时,它必须从磁盘读取它。

第二次,它可能只是从RAM中读取缓冲区

缓存。


-

格兰特爱德华兹格兰特哇! Catsup和Mustard

到处都是!它是

visi.com人类汉堡包!


Hi all,

I am running Python 2.5 on Feisty Ubuntu. I came across some code that
is substantially slower when in a method than in a function.

################# START SOURCE #############
# The function

def readgenome(filehandle):
s = ''''
for line in filehandle.xreadlines():
if ''>'' in line:
continue
s += line.strip()
return s

# The method in a class
class bar:
def readgenome(self, filehandle):
self.s = ''''
for line in filehandle.xreadlines():
if ''>'' in line:
continue
self.s += line.strip()

################# END SOURCE ##############
When running the function and the method on a 20,000 line text file, I
get the following:

>>cProfile.run("bar.readgenome(open(''cb_foo''))")

20004 function calls in 10.214 CPU seconds

Ordered by: standard name

ncalls tottime percall cumtime percall
filename:lineno(function)
1 0.000 0.000 10.214 10.214 <string>:1(<module>)
1 10.205 10.205 10.214 10.214 reader.py:11(readgenome)
1 0.000 0.000 0.000 0.000 {method ''disable'' of
''_lsprof.Profiler'' objects}
19999 0.009 0.000 0.009 0.000 {method ''strip'' of ''str''
objects}
1 0.000 0.000 0.000 0.000 {method ''xreadlines'' of
''file'' objects}
1 0.000 0.000 0.000 0.000 {open}

>>cProfile.run("z=r.readgenome(open(''cb_foo''))")

20004 function calls in 0.041 CPU seconds

Ordered by: standard name

ncalls tottime percall cumtime percall
filename:lineno(function)
1 0.000 0.000 0.041 0.041 <string>:1(<module>)
1 0.035 0.035 0.041 0.041 reader.py:2(readgenome)
1 0.000 0.000 0.000 0.000 {method ''disable'' of
''_lsprof.Profiler'' objects}
19999 0.007 0.000 0.007 0.000 {method ''strip'' of ''str''
objects}
1 0.000 0.000 0.000 0.000 {method ''xreadlines'' of
''file'' objects}
1 0.000 0.000 0.000 0.000 {open}
The method takes 10 seconds, the function call 0.041 seconds!

Yes, I know that I wrote the underlying code rather inefficiently, and
I can streamline it with a single file.read() call instead if an
xreadlines() + strip loop. Still, the differences in performance are
rather staggering! Any comments?

Thanks,

Iddo

解决方案

On 2007-06-14, id****@gmail.com <id****@gmail.comwrote:

Hi all,

I am running Python 2.5 on Feisty Ubuntu. I came across some code that
is substantially slower when in a method than in a function.

################# START SOURCE #############
# The function

def readgenome(filehandle):
s = ''''
for line in filehandle.xreadlines():
if ''>'' in line:
continue
s += line.strip()
return s

# The method in a class
class bar:
def readgenome(self, filehandle):
self.s = ''''
for line in filehandle.xreadlines():
if ''>'' in line:
continue
self.s += line.strip()

################# END SOURCE ##############
When running the function and the method on a 20,000 line text file, I
get the following:

>>>cProfile.run("bar.readgenome(open(''cb_foo''))" )

20004 function calls in 10.214 CPU seconds

Ordered by: standard name

ncalls tottime percall cumtime percall
filename:lineno(function)
1 0.000 0.000 10.214 10.214 <string>:1(<module>)
1 10.205 10.205 10.214 10.214 reader.py:11(readgenome)
1 0.000 0.000 0.000 0.000 {method ''disable'' of
''_lsprof.Profiler'' objects}
19999 0.009 0.000 0.009 0.000 {method ''strip'' of ''str''
objects}
1 0.000 0.000 0.000 0.000 {method ''xreadlines'' of
''file'' objects}
1 0.000 0.000 0.000 0.000 {open}

>>>cProfile.run("z=r.readgenome(open(''cb_foo''))" )

20004 function calls in 0.041 CPU seconds

Ordered by: standard name

ncalls tottime percall cumtime percall
filename:lineno(function)
1 0.000 0.000 0.041 0.041 <string>:1(<module>)
1 0.035 0.035 0.041 0.041 reader.py:2(readgenome)
1 0.000 0.000 0.000 0.000 {method ''disable'' of
''_lsprof.Profiler'' objects}
19999 0.007 0.000 0.007 0.000 {method ''strip'' of ''str''
objects}
1 0.000 0.000 0.000 0.000 {method ''xreadlines'' of
''file'' objects}
1 0.000 0.000 0.000 0.000 {open}
The method takes 10 seconds, the function call 0.041 seconds!

Yes, I know that I wrote the underlying code rather
inefficiently, and I can streamline it with a single
file.read() call instead if an xreadlines() + strip loop.
Still, the differences in performance are rather staggering!
Any comments?

It is likely the repeated attribute lookup, self.s, that''s
slowing it down in comparison to the non-method version.

Try the following simple optimization, using a local variable
instead of an attribute to build up the result.

# The method in a class
class bar:
def readgenome(self, filehandle):
s = ''''
for line in filehandle.xreadlines():
if ''>'' in line:
continue
s += line.strip()
self.s = s

To further speed things up, think about using the str.join idiom
instead of str.+=, and using a generator expression instead of an
explicit loop.

# The method in a class
class bar:
def readgenome(self, filehandle):
self.s = ''''.join(line.strip() for line in filehandle)

--
Neil Cerutti


En Wed, 13 Jun 2007 21:40:12 -0300, <id****@gmail.comescribió:

Hi all,

I am running Python 2.5 on Feisty Ubuntu. I came across some code that
is substantially slower when in a method than in a function.

################# START SOURCE #############
# The function

def readgenome(filehandle):
s = ''''
for line in filehandle.xreadlines():
if ''>'' in line:
continue
s += line.strip()
return s

# The method in a class
class bar:
def readgenome(self, filehandle):
self.s = ''''
for line in filehandle.xreadlines():
if ''>'' in line:
continue
self.s += line.strip()

In the function above, s is a local variable, and accessing local
variables is very efficient (using an array of local variables, the
compiler assigns statically an index for each one).
Using self.s, on the other hand, requires a name lookup for each access.
The most obvious change would be to use a local variable s, and assign
self.s = s only at the end. This should make both methods almost identical
in performance.
In addition, += is rather inefficient for strings; the usual idiom is
using ''''.join(items)
And since you have Python 2.5, you can use the file as its own iterator;
combining all this:

return ''''.join(line.strip() for line in filehandle if ''>'' not in line)

--
Gabriel Genellina


On 2007-06-14, id****@gmail.com <id****@gmail.comwrote:

The method takes 10 seconds, the function call 0.041 seconds!

What happens when you run them in the other order?

The first time you read the file, it has to read it from disk.
The second time, it''s probably just reading from the buffer
cache in RAM.

--
Grant Edwards grante Yow! Catsup and Mustard
at all over the place! It''s
visi.com the Human Hamburger!


这篇关于方法比功能慢得多?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆