如何进一步优化这个python脚本?
我创建这个脚本是为了在python中计算。有什么办法可以让它跑得更快吗如何进一步优化这个python脚本?,python,optimization,micro-optimization,Python,Optimization,Micro Optimization,我创建这个脚本是为了在python中计算。有什么办法可以让它跑得更快吗 tries = input() while tries > 0: mainstr = raw_input() tot = 0 ml = len(mainstr) for i in xrange(ml): j = 0 substr = mainstr[i:] ll = len(substr) for j in xrange(l
tries = input()
while tries > 0:
mainstr = raw_input()
tot = 0
ml = len(mainstr)
for i in xrange(ml):
j = 0
substr = mainstr[i:]
ll = len(substr)
for j in xrange(ll):
if substr[j] != mainstr[j]:
break
j = j + 1
tot = tot + j
print tot
tries = tries - 1
编辑:在应用一些优化后,这是代码,但这还不够
tries = int(raw_input())
while tries > 0:
mainstr = raw_input()
tot = 0
ml = len(mainstr)
for i in xrange(ml):
for j in xrange(ml-i):
if mainstr[i+j] != mainstr[j]:
break
j += 1
tot += j
print tot
tries = tries - 1
编辑2:代码的第三个版本。还是不行
def mf():
tries = int(raw_input())
for _ in xrange(tries):
mainstr = raw_input()
tot = 0
ml = len(mainstr)
for i in xrange(ml):
for j in xrange(ml-i):
if mainstr[i+j] != mainstr[j]:
break
j += 1
tot += j
print tot
mf()
您可以跳过循环内的内存分配
substr=mainstr[i::
不必要地分配新字符串。您只能在substr[j]!=mainstr[j]
,相当于mainstr[i+j]!=mainstr[j]
,因此不需要构建substr
内存分配非常昂贵,因此您希望避免在紧循环中进行内存分配。您可以跳过循环中的内存分配
substr=mainstr[i::
不必要地分配新字符串。您只能在substr[j]!=mainstr[j]
,相当于mainstr[i+j]!=mainstr[j]
,因此不需要构建substr
内存分配是昂贵的,因此您希望避免它们在紧循环中出现。如果您使用
i=mainstr.find(mainstr[0],i+1)
而不是检查所有i
,您可以通过一个常数因子来改进它。i==0的特殊情况也会有所帮助
将代码放入函数中。它还可能以一个恒定的因子加速事情
对…使用。。。否则:j+=1
,以避免在每个步骤中增加j
尝试找到一个比O(n**2)更好的算法,该算法利用比较字符串所有后缀的事实
most比CPython快100倍(Pypy快10-30倍),并通过了挑战:
import os
def string_similarity(string, _cp=os.path.commonprefix):
return sum(len(_cp([string, string[i:]])) for i in xrange(len(string)))
for _ in xrange(int(raw_input())):
print string_similarity(raw_input())
上面的优化只提供了几个百分点的改进,它们不足以通过CPython中的挑战(Python的时间限制只比CPython大8倍)
以下各项之间几乎没有区别(在CPython中):
以及:
如果使用
i=mainstr.find(mainstr[0],i+1)
而不是检查所有i
,则可以通过一个常数因子来改进它。i==0的特殊情况也会有所帮助
将代码放入函数中。它还可能以一个恒定的因子加速事情
对…使用。。。否则:j+=1
,以避免在每个步骤中增加j
尝试找到一个比O(n**2)更好的算法,该算法利用比较字符串所有后缀的事实
most比CPython快100倍(Pypy快10-30倍),并通过了挑战:
import os
def string_similarity(string, _cp=os.path.commonprefix):
return sum(len(_cp([string, string[i:]])) for i in xrange(len(string)))
for _ in xrange(int(raw_input())):
print string_similarity(raw_input())
上面的优化只提供了几个百分点的改进,它们不足以通过CPython中的挑战(Python的时间限制只比CPython大8倍)
以下各项之间几乎没有区别(在CPython中):
以及:
这是我的。它通过了测试用例,但可能不是绝对最快的
import sys
def simstring(string, other):
val = 0
for l, r in zip(string, other):
if l != r:
return val
val += 1
return val
dsize = sys.stdin.readline()
for i in range(int(dsize)):
ss = 0
string = sys.stdin.readline().strip()
suffix = string
while suffix:
ss += simstring(string, suffix)
suffix = suffix[1:]
sys.stdout.write(str(ss)+"\n")
这是我的。它通过了测试用例,但可能不是绝对最快的
import sys
def simstring(string, other):
val = 0
for l, r in zip(string, other):
if l != r:
return val
val += 1
return val
dsize = sys.stdin.readline()
for i in range(int(dsize)):
ss = 0
string = sys.stdin.readline().strip()
suffix = string
while suffix:
ss += simstring(string, suffix)
suffix = suffix[1:]
sys.stdout.write(str(ss)+"\n")
对于这种简单的数字脚本,您只需做两件事:
- 使用PyPy(它没有复杂的依赖关系,速度会大大加快)
- 将大部分代码放入函数中。这大大加快了CPython和PyPy的速度。而不是: 一些代码
fijal对于这种简单的数字脚本,您只需要做两件事:
- 使用PyPy(它没有复杂的依赖关系,速度会大大加快)
- 将大部分代码放入函数中。这大大加快了CPython和PyPy的速度。而不是: 一些代码
fijal也许更适合于?嗯,
j=j+1
语句肯定可以删除,因为j
将立即被覆盖。这同样适用于j=0
语句。使用trys=int(raw\u input())
您可以在xrange(trys)中使用而不是whileloop@EdwinDrood当前位置我的机器和ideone都这么说。虽然在您的情况下,这并不重要(测试的数量可能更适合?嗯,j=j+1
语句肯定可以被删除,因为j
将立即被覆盖。j=0
语句也是如此。使用trys=int(原始输入())
您可以在xrange(trys)中使用for u
而不是whileloop@EdwinDrood当前位置我的机器和ideone都这么说。不过对你来说,这不重要(测试次数仍然超过时间限制0.2s
@EdwinDrood:我无法打开你发布的链接,因为它不接受我的旧Firefox。但一般来说,在计算字符串相似性时,你会使用某种动态编程算法,例如维基百科上列出的算法。仍然超过时间限制0.2s
@Ed。)winDrood:嗯,我不能打开你发布的链接,因为它不接受我以前的Firefox。但一般来说,在计算字符串相似性时,你会使用某种动态编程算法,例如Wikipedia上列出的。@larsmans:尝试一些简单的方法,比如:I=0\n,而在模块级和内部,I<1000000:I+=1
一个函数。你自己看。我立刻相信了你,我只是想知道它是如何工作的:)顶级代码的编译方式是否不同?@larsmans:我想访问全局名称的速度比访问本地名称的速度慢。@larsmans:尝试一些简单的方法,例如:I=0\n而我<1000000:I+=1
在模块级和函数内部。你自己看看。我立刻相信了你,我只是想知道这是如何工作的:)顶级代码的编译是否不同?@larsmans:我猜访问全局名称的速度比访问本地名称的速度慢。您的似乎比我的慢!我用10000
chars进行了测试,您的大约用了8秒。我的大约是4.8秒。啊,就像我说的,它可以改进。但很难比较不同ma的时间
def main():
some_code
if __name__ == '__main__':
main()