【发布时间】:2011-06-26 13:17:34
【问题描述】:
下面的代码sn-p计算给定数的素因数:
public static LinkedList<Long> getPrimeFactors(Long number) {
LinkedList<Long> primeFactors = new LinkedList<Long>();
for (Long factor = Long.valueOf(2); factor <= number / factor; factor++) {
if (number % factor == 0) {
primeFactors.add(factor);
while (number % factor == 0) {
number /= factor;
}
}
}
if (number > 1) {
primeFactors.add(number);
}
return primeFactors;
}
计算 9223372036854775783 的素数需要 140937 毫秒(它是小于Long.MAX_VALUE 的最后一个素数)。有没有办法通过并发实现这种分解,即使用ExecutorService?
编辑:
public static void getPrimeFactors(Long number) {
LinkedList<Long> primeFactors = new LinkedList<Long>();
if (number % 2 == 0) {
primeFactors.add(2L);
while (number % 2 == 0) {
number /= 2;
}
}
long limit = (long) Math.sqrt(number) + 1;
ExecutorService service = Executors.newFixedThreadPool(2);
LinkedList<Future<LinkedList<Long>>> futures = new LinkedList<Future<LinkedList<Long>>>();
futures.add(service.submit(new PrimeFactor(3, limit / 2, number)));
futures.add(service.submit(new PrimeFactor(1 + limit / 2, limit, number)));
for (Future<LinkedList<Long>> future : futures) {
try {
primeFactors.addAll(future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
service.shutdown();
if(number>1) {
primeFactors.add(number);
}
System.out.println(primeFactors);
}
private static class PrimeFactor implements Callable<LinkedList<Long>> {
private long lowerLimit;
private long upperLimit;
private Long number;
public PrimeFactor(long lowerLimit, long upperLimit, Long number) {
this.lowerLimit = lowerLimit;
this.upperLimit = upperLimit;
this.number = number;
}
public LinkedList<Long> call() throws Exception {
LinkedList<Long> primeFactors = new LinkedList<Long>();
for (long i = lowerLimit; i < upperLimit; i += 2) {
if (number % i == 0) {
primeFactors.add(i);
while (number % 2 == 0) {
number /= i;
}
}
}
return primeFactors;
}
}
第二次编辑:
public static LinkedList<Long> getPrimeFactorsByFastGeneralMethod(long number) {
LinkedList<Long> primeFactors = new LinkedList<Long>();
if (number % 2 == 0) {
primeFactors.add(2L);
while (number % 2 == 0) {
number /= 2;
}
}
long limit = (long) Math.sqrt(number);
for (long factor = 3; factor <= limit; factor += 2) {
if (number % factor == 0) {
primeFactors.add(factor);
while (number % factor == 0) {
number /= factor;
}
}
}
if (number > 1) {
primeFactors.add(number);
}
return primeFactors;
}
现在代码 sn-p:
LinkedList<Long> primeFactors = Factorization.getPrimeFactorsByConcurrentGeneralMethod(600851475143L);
System.out.println("Result: " + primeFactors.get(primeFactors.size() - 1));
primeFactors = Factorization.getPrimeFactorsByFastGeneralMethod(600851475143L);
System.out.println("Result: " + primeFactors.get(primeFactors.size() - 1));
正在给出输出:
Result: 600851475143
Result: 6857
注意:类名是Factorization,我把方法名getPrimeFactors改成了getPrimeFactorsByConcurrentGeneralMethod
【问题讨论】:
-
第一个明显的改进是将
Long变量替换为long变量。这减少了装箱和拆箱包装器对象的开销。 -
@Christian Semrau 主要是我用
BigInteger代替Long写的。
标签: java concurrency prime-factoring