[英]Python code works 20 times slower than Java. Is there a way to speed up Python?
I wrote a program in Python and in Java to search for the smallest integer solution of the equation: 我用Python和Java编写了一个程序来搜索方程的最小整数解:
a^5+b^5+c^5+d^5=e^5 (expected output is 133^5+110^5+84^5+27^5=144^5) a ^ 5 + b ^ 5 + c ^ 5 + d ^ 5 = e ^ 5(预期输出为133 ^ 5 + 110 ^ 5 + 84 ^ 5 + 27 ^ 5 = 144 ^ 5)
Powers and roots are either computed directly ("direct calculation" method) or computed and stored in an array ("power lookup" method). 幂和根可以直接计算(“直接计算”方法),也可以计算并存储在数组中(“功率查找”方法)。 Fifth powers are looked up like n5 = fifth_power[n].
查找五次幂,例如n5 = third_power [n]。 Fifth power root is computed using a binary search in array 'fifth_power`.
第五幂根是使用数组'fifth_power`中的二进制搜索来计算的。
I am running it on NetBeans if it matters. 如果重要的话,我可以在NetBeans上运行它。 It takes:
它需要:
30. s (Python, direct)
20. s (Python, lookup)
5.6 s (Java, direct)
0.8 s (Java, lookup)
Is there a way to boost Python performance? 有没有办法提高Python性能? I am not looking for better math (sieving of some kind).
我不是在寻找更好的数学(某种筛分法)。 I am looking for better implementation of "for each combination of a,b,c,d compute some of their powers, check if the sum is a perfect power. If it is - print the result".
我正在寻找更好的实现方式,“对于a,b,c,d的每个组合,计算其幂的一些,检查总和是否为完美幂。如果是,则打印结果”。
Is it expected that Python runs some 20 times slower than Java? 难道Python运行速度比Java慢20倍吗?
Python 3.5 Python 3.5
http://pastebin.com/qVthWGKm http://pastebin.com/qVthWGKm
from array import *
import math
import time
#PYTHON, BRUTEFORCE : ~30 s
millis1 = int(round(time.time() * 1000))
keep_searching = True
a=1
result=""
while(keep_searching):
a+=1
for b in range(1,a+1):
for c in range(1,b+1):
for d in range(1,c+1):
sum=math.pow(a,5)+math.pow(b,5)+math.pow(c,5)+math.pow(d,5)
root = math.pow(sum,0.2)
e = round(root)
e5 = math.pow(e,5)
if(e5==sum):
result="{}^5 + {}^5 + {}^5 + {}^5 = {}^5".format(int(a),int(b), int(c),int(d), int(e))
keep_searching = False
millis2 = int(round(time.time() * 1000))
print(result)
print("Found solution in {} ms".format(millis2-millis1))
#PYTHON, PRECOMPUTE POWERS: ~20 s
millis3 = int(round(time.time() * 1000))
#fifth_power #175 is enough
size=176
fifth_power = [None] * size
for i in range(size):
fifth_power[i]=long(math.pow(i,5))
millis4 = int(round(time.time() * 1000))
#returns value if it is a perfect power (32 returns 2)
#returns -1 if between perfect powers, -2 if greater than max value in array, -3 if smaller than min value in array
def check_perfect_power(number, min, max, fifth_power):
current=int((min+max)/2)
while(max>=min):
if(number==fifth_power[current]):
return current
elif(number>fifth_power[current]):
min=current+1
current=int((max+min)/2)
else:
max=current-1
current=int((max+min)/2)
if(min>=len(fifth_power)):
return -2
if(max<0):
return -3
return -1
keep_searching = True
a=0
result=""
while(keep_searching):
a+=1
for b in range(1,a+1):
for c in range(1,b+1):
for d in range(1,c+1):
mymax=min(int(a*1.32)+1, size-1)
e=check_perfect_power(fifth_power[a]+fifth_power[b]+fifth_power[c]+fifth_power[d], a, mymax, fifth_power)
if(e>0):
result="{}^5 + {}^5 + {}^5 + {}^5 = {}^5".format(int(a),int(b), int(c),int(d), int(e))
keep_searching = False
millis5 = int(round(time.time() * 1000))
print(result)
print("Populated in {} ms, find solution in {} ms".format(millis4-millis3,millis5-millis4))
Java 8: Java 8:
http://pastebin.com/G4V3fHnD http://pastebin.com/G4V3fHnD
import java.util.ArrayList;
public class Eu514 {
public static void main(String[] args) {
bruteforce(); //Solution found by bruteforce in 5600 ms.
prepopulate(); //Solution found by prepopulation in 761 ms.
}
public static void bruteforce(){ //JAVA BRUTEFORCE
Long t2 = 0L;
Long t1 = System.currentTimeMillis();
boolean keepSearching = true;
int a = 0;
long e = 0;
String solution = "";
while (keepSearching) {
a++;
for (int b = 1; b <= a; b++) {
for (int c = 1; c <= b; c++) {
for (int d = 1; d <= c; d++) {
long sum = (long) (Math.pow(a, 5) + Math.pow(b, 5) + Math.pow(c, 5) + Math.pow(d, 5)); //sum=a^5+b^5+c^5+d^5
e = Math.round(Math.pow(sum, 0.2)); //e= sum^(1/5), rounded
long e5 = (long) Math.pow(e,5); //e^5
if(e5==sum){
t2 = System.currentTimeMillis();
solution = a + "^5 + " + b + "^5 + " + c + "^5 + " + d + "^5 = " + e + "^5";
keepSearching = false;
}
}
}
}
}
long delta = ((t2-t1));
System.out.println(solution+"\nSolution found by bruteforce in "+delta+" ms.");
}
public static void prepopulate(){ //JAVA PREPOPULATE
Long t2 = 0L;
Long t1 = System.currentTimeMillis();
int size = 176;
long[] powers = populatePowers(size);
boolean keepSearching = true;
int a = 0;
int e = 0;
String solution = "";
while (keepSearching) {
a++;
for (int b = 1; b <= a; b++) {
for (int c = 1; c <= b; c++) {
for (int d = 1; d <= c; d++) {
long sum = powers[a] + powers[b] + powers[c] + powers[d];
int max = (int) Math.min(size - 1, (a * 1.32 + 1));
e = checkIfPerfectPower(sum, a, max, powers);
if (e > 0) {
t2 = System.currentTimeMillis();
solution = a + "^5 + " + b + "^5 + " + c + "^5 + " + d + "^5 = " + e + "^5";
keepSearching = false;
}
}
}
}
}
long delta = ((t2-t1));
System.out.println(solution+"\nSolution found by prepopulation in "+delta+" ms.");
}
public static long[] populatePowers(int max){
long[] powers = new long[max];
for (int i = 0; i < powers.length; i++) {
powers[i]=(long) Math.pow(i,5);
}
return powers;
}
public static int checkIfPerfectPower(long number, int min, int max, long[] arr){
int current =((min+max)/2);
while(max>=min){
if(number==arr[current]){
return current;
}else if(number>arr[current]){
min = current + 1;
current = (max + min) / 2;
}else{
max=current-1;
current=(max+min)/2;
}
}
if(min>=arr.length) return -2;
if(max<0) return -3;
return -1;
}
}
from array import *
import time
import numpy as np
#PYTHON, BRUTEFORCE : ~30 s
millis1 = int(round(time.time() * 1000))
keep_searching = True
a = 1
result = ""
while(keep_searching):
a += 1
a_pow = a ** 5
for b in xrange(1, a+1):
b_pow = b ** 5
for c in xrange(1, b+1):
c_pow = c ** 5
for d in xrange(1, c+1):
d_pow = d ** 5
sum_pow = a_pow + b_pow + c_pow + d_pow
root = sum_pow ** 0.2
e = round(root)
e5 = e ** 5
if(e5 == sum_pow):
result="{}^5 + {}^5 + {}^5 + {}^5 = {}^5".format(a, b, c, d, e)
keep_searching = False
millis2 = int(round(time.time() * 1000))
print(result)
print("Found solution in {} ms".format(millis2-millis1))
Python 2.7, with some code optimizations Python 2.7,并进行了一些代码优化
133^5 + 110^5 + 84^5 + 27^5 = 144.0^5 Found solution in 8333 ms 133 ^ 5 + 110 ^ 5 + 84 ^ 5 + 27 ^ 5 = 144.0 ^ 5在8333毫秒内找到了解决方案
It could be a little different from CPU to CPU. 每个CPU可能略有不同。
What about improving the java code? 改进Java代码呢?
int size = 200;
long[] pow5 = new long[size];
for (int i = 1; i < size; ++i)
{
long sqr = i * i;
pow5[i] = sqr * sqr * i;
}
for (int a = 1; a < size; ++a)
{
for (int b = 1; b <= a; ++b)
{
for (int c = 1; c <= b; ++c)
{
int e = a + 1;
for (int d = 1; d <= c; ++d)
{
long sum = pow5[a] + pow5[b] + pow5[c] + pow5[d];
while(pow5[e] < sum){ e++; }
if (pow5[e] == sum)
{
System.out.println(a + "^5 + " + b + "^5 + " + c + "^5 + " + d + "^5 = " + e + "^5");
return;
}
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.