如何解决Python multi-and语句比Java multi-and语句花费的时间长得多
Java:
//Euler5 ~ Smallest multiple
import java.util.concurrent.TimeUnit;
public class Euler5
{
public static void main(String[] args) throws InterruptedException
{
long startTime = System.nanoTime();
int i = 2520;
do
{
i++;
if(((i%2)==0)&&
((i%3)==0)&&
((i%4)==0)&&
((i%5)==0)&&
((i%6)==0)&&
((i%7)==0)&&
((i%8)==0)&&
((i%9)==0)&&
((i%10)==0)&&
((i%11)==0)&&
((i%12)==0)&&
((i%13)==0)&&
((i%14)==0)&&
((i%15)==0)&&
((i%16)==0)&&
((i%17)==0)&&
((i%18)==0)&&
((i%19)==0)&&
((i%20)==0))
{
break;
}
} while(true);
long endTime = System.nanoTime();
long timeElapsed = endTime - startTime;
System.out.println("Solution: " + i + "\n");
System.out.println("Program completed in " + timeElapsed/1000000000 + " seconds.");
}
}
完成时间不到1秒。
Python:
#Euler5 ~ Smallest multiple
import timeit
start = timeit.default_timer()
i = 2520;
while(1):
i = i + 1
if i%2 == 0 and \
i%3 == 0 and \
i%4 == 0 and \
i%5 == 0 and \
i%6 == 0 and \
i%7 == 0 and \
i%8 == 0 and \
i%9 == 0 and \
i%10 == 0 and \
i%11 == 0 and \
i%12 == 0 and \
i%13 == 0 and \
i%14 == 0 and \
i%15 == 0 and \
i%16 == 0 and \
i%17 == 0 and \
i%18 == 0 and \
i%19 == 0 and \
i%20 == 0:
break
stop = timeit.default_timer()
cpu_time = stop - start
if(cpu_time > 200):
print("Runtime has exceeded requirement.\n")
print("Possible solution:",i,"\n")
print("Program completed in",cpu_time,"seconds.")
exit()
#stop = timeit.default_timer()
#print("Solution: ","\n")
#print("Program completed in","{0:.3f}".format(stop - start),"seconds.")
完成时间为116.948秒。
Euler项目有一个软规则,程序可以在60或更短的时间内找到解决方案。除了嵌套20个if循环外,我想不出一种简化Python程序的方法,但这似乎要付出更多的代价。而且由于Java实现是如此之快,它使我想知道编写循环的方式是否存在问题,例如使用\字符。我想知道到底是什么原因导致运行时出现如此巨大的差距。
如何减少Python程序的运行时间,使其与Java程序更加匹配?
解决方法
听从@Andreas的建议,删除
stop = timeit.default_timer()
从while循环内部将我的运行时间从115s减少到53s。
然后再次听Andreas的意见,取消了一些模数检查,将时间减少到只有39s。
#Euler5 ~ Smallest multiple
import timeit
start = timeit.default_timer()
i = 2520;
while(1):
i = i + 1
if i%20 == 0 and \
i%19 == 0 and \
i%18 == 0 and \
i%17 == 0 and \
i%16 == 0 and \
i%14 == 0 and \
i%13 == 0 and \
i%11 == 0:
break
stop = timeit.default_timer()
print("Solution: ",i,"\n")
print("Program completed in","{0:.3f}".format(stop - start),"seconds.")
我认为与Java相比,时间上的剩余差异是由于@tdelaney建议的,例如Python中的编译器不会尝试采用快捷方式。因此,如果其中一种模检查为假,那么我猜想它仍然会遍历所有模检查。
这意味着必须使用巧妙的方法来进一步减少时间。听听@Klaus D.的建议,并利用LCM的素因分解方法
#Euler5 ~ Smallest multiple
import timeit
start = timeit.default_timer()
#List of primes < 100
primes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
N = input("Choose N < 100 to find LCM using Prime Factorization: ")
product = 1
i = 0
j = 2
while(1):
if primes[i] > int(N):
break
while(1):
exp = pow(primes[i],j)
if exp > int(N):
break
j = j + 1
product = product * pow(primes[i],j-1)
i = i + 1
j = 2
stop = timeit.default_timer()
print("Solution: ",product,"seconds.")
产生的运行时间仅为0.643s!
Java似乎不会从这种优化中受益匪浅,但是显然Python需要特别注意,因为它是一种脚本语言。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。