微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python multi-and语句比Java multi-and语句花费的时间长得多

如何解决Python multi-and语句比Java multi-and语句花费的时间长得多

我有以下两个程序搜索N,其中(N%i == 0)等于[2

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 举报,一经查实,本站将立刻删除。