在我的班级中,我们被分配了一个问题来创建一个'factorizer'应用程序,该应用程序计算任何数字的素数因子分解,直到非常大的数字。他给了我们一个Number.java
课程,用于计算这个数字是否为素数用于显而易见的用途。
// Number.java
public class Number {
long n;
public Number(long number) {
n = number;
}
boolean isPrime() {
for(long k = 2; k < n; k++) {
if(n % k == 0) return false;
}
return true;
}
}
唯一的问题是Number.java
类是它有一个构造函数,在我看来它在这种情况下不那么“移动”。我的意思是,在我的循环中计算参数的素因子,一个又一个地创建一个新的Number对象。在顶部定义private Number isPrimeFactor = new Number()
而不是为循环的每次重复创建新的Number isPrimeFactor = new Number(i)
会不会更有意义?我向老师询问了这件事,但他并没有真正回答。这是我正在谈论的一些示例代码。
while (remainder!=0 && j<n) {
Number isFactor = new Number(j);
if(isFactor.isPrime() && remainder%j==0) {
remainder = remainder / j;
factor[i]=j;
temp = (int) j;
multiplicity[temp] = multiplicity[temp]+1;
i++;
} else {
j++;
}
}
答案 0 :(得分:2)
是的,new
相当昂贵,这意味着调用几千次isPrimeFactor = new Number(j)
的效率低于仅Number
的一个实例并更改关联的n
值比方说,isPrimeFactor.setN(j)
。那是因为new
分配了新的内存,一旦实例不再可用,垃圾收集器会不时释放内存。
顺便说一句,我认为你的教授给出的Number
课是一个糟糕的OO设计,可变或不可变。
答案 1 :(得分:1)
这里有意义的是不拥有一个构造函数,其唯一目的是将n
传递给isPrime()
:这就是函数参数的用途!
public class PrimeChecker {
public static boolean isPrime(long n) {
for(long k = 2; k * k < n; k++) {
if(n % k == 0) return false;
}
return true;
}
}
答案 2 :(得分:0)
在内存/速度/代码可读性/维护性之间总是有选择。因此,不可能以客观的方式回答这个问题。
这种解决方案效率低下吗?也许,但话说再次,函数调用很昂贵,因此涉及函数调用的任何解决方案都可能被标记为低效。
如果这是家庭作业或学习练习,那么代码效率并不是很重要,但制作解释所涉及概念的清晰代码非常重要!
的PS。
我见过的大多数代码检查质数都有一个方法“isPrime”,它以一个数字/整数作为参数。
答案 3 :(得分:0)
除了其他优化之外,没有理由为这些优化创建数字,整数等。您可以使用以下内容跳过上述所有内容:
public static boolean isPrime(long number) {
for(long k = 2; k < n; k++) {
if(n % k == 0) return false;
}
return true;
}
答案 4 :(得分:0)
仅重复实例化一次并重复分配其字段肯定会更快。但是,在这种情况下,测试isPrime
可能是瓶颈,因此您几乎不会注意到差异。
答案 5 :(得分:-2)
你是对的,在循环中分配对象是一种性能反模式。 相反,您可以通过使用静态类成员来提高执行速度并提高内存使用率。
// Number.java
public class Number {
private static long n;
public static void setNumber(long number){
n = number;
}
static boolean isPrime() {
for(long k = 2; k < n; k++) {
if(n % k == 0) return false;
}
return true;
}
}