//array could be Integer.MAX_VALUE length
private long canocicalSum(int[] array) {
int sum = 0;
for (int i = 0; i < array.length; i++)
sum += array[i];
return sum;
}
问题1[主]:是否可以优化canonicalsum
?
我尝试过:避免使用非常大的数字的操作。所以我决定使用辅助数据。例如,我将array1[100]
转换为array2[10]
,其中array2[I]=array1[I]+array1[I+1]+array1[I+9]
。
private long optimizedSum(int[] array, int step) {
do {
array = sumItr(array, step);
} while (array.length != 1);
return array[0];
}
private int[] sumItr(int[] array, int step) {
int length = array.length / step + 1;
boolean needCompensation = (array.length % step == 0) ? false : true;
int aux[] = new int[length];
for (int i = 0, auxSum = 0, auxPointer = 0; i < array.length; i++) {
auxSum += array[i];
if ((i + 1) % step == 0) {
aux[auxPointer++] = auxSum;
auxSum = 0;
}
if (i == array.length - 1 && needCompensation) {
aux[auxPointer++] = auxSum;
}
}
return aux;
}
问题:但是canonicalsum
似乎比optimizedsum
快十倍。这里是我的测试:
@Test
public void sum_comparison() {
final int ARRAY_SIZE = 100000000;
final int STEP = 1000;
int[] array = genRandomArray(ARRAY_SIZE);
System.out.println("Start canonical Sum");
long beg1 = System.nanoTime();
long sum1 = canocicalSum(array);
long end1 = System.nanoTime();
long time1 = end1 - beg1;
System.out.println("canon:" + TimeUnit.MILLISECONDS.convert(time1, TimeUnit.NANOSECONDS) + "milliseconds");
System.out.println("Start optimizedSum");
long beg2 = System.nanoTime();
long sum2 = optimizedSum(array, STEP);
long end2 = System.nanoTime();
long time2 = end2 - beg2;
System.out.println("custom:" + TimeUnit.MILLISECONDS.convert(time2, TimeUnit.NANOSECONDS) + "milliseconds");
assertEquals(sum1, sum2);
assertTrue(time2 <= time1);
}
private int[] genRandomArray(int size) {
int[] array = new int[size];
Random random = new Random();
for (int i = 0; i < array.length; i++) {
array[i] = random.nextInt();
}
return array;
}
问题1[主]:是否可能优化CanonicalSum?
是的,是的。但我不知道是什么因素造成的。
您可以做的一些事情是:
for (int x = 0; x < 100; x++)
{
delete(x);
}
for (int x = 0; x < 100; x+=5)
{
delete(x);
delete(x+1);
delete(x+2);
delete(x+3);
delete(x+4);
}
这里可以看到多线程方法的数学运算的实现。
Java7中引入的fork/join框架的示例实现基本上完成了上面的分而治之算法所做的工作:
public class ForkJoinCalculator extends RecursiveTask<Double> {
public static final long THRESHOLD = 1_000_000;
private final SequentialCalculator sequentialCalculator;
private final double[] numbers;
private final int start;
private final int end;
public ForkJoinCalculator(double[] numbers, SequentialCalculator sequentialCalculator) {
this(numbers, 0, numbers.length, sequentialCalculator);
}
private ForkJoinCalculator(double[] numbers, int start, int end, SequentialCalculator sequentialCalculator) {
this.numbers = numbers;
this.start = start;
this.end = end;
this.sequentialCalculator = sequentialCalculator;
}
@Override
protected Double compute() {
int length = end - start;
if (length <= THRESHOLD) {
return sequentialCalculator.computeSequentially(numbers, start, end);
}
ForkJoinCalculator leftTask = new ForkJoinCalculator(numbers, start, start + length/2, sequentialCalculator);
leftTask.fork();
ForkJoinCalculator rightTask = new ForkJoinCalculator(numbers, start + length/2, end, sequentialCalculator);
Double rightResult = rightTask.compute();
Double leftResult = leftTask.join();
return leftResult + rightResult;
}
}
在这里,我们开发了一个recursivetask
来拆分一个数组,直到子数组的长度不低于给定的阈值。此时,子数组将按顺序进行处理,并对其应用由以下接口定义的操作
public interface SequentialCalculator {
double computeSequentially(double[] numbers, int start, int end);
}
public static double varianceForkJoin(double[] population){
final ForkJoinPool forkJoinPool = new ForkJoinPool();
double total = forkJoinPool.invoke(new ForkJoinCalculator(population, new SequentialCalculator() {
@Override
public double computeSequentially(double[] numbers, int start, int end) {
double total = 0;
for (int i = start; i < end; i++) {
total += numbers[i];
}
return total;
}
}));
final double average = total / population.length;
double variance = forkJoinPool.invoke(new ForkJoinCalculator(population, new SequentialCalculator() {
@Override
public double computeSequentially(double[] numbers, int start, int end) {
double variance = 0;
for (int i = start; i < end; i++) {
variance += (numbers[i] - average) * (numbers[i] - average);
}
return variance;
}
}));
return variance / population.length;
}
本文向大家介绍如何进行大表优化?相关面试题,主要包含被问及如何进行大表优化?时的应答技巧和注意事项,需要的朋友参考一下 当MySQL单表记录数过大时,数据库的CRUD性能会明显下降,一些常见的优化措施如下: 1. 限定数据的范围 务必禁止不带任何限制数据范围条件的查询语句。比如:我们当用户在查询订单历史的时候,我们可以控制在一个月的范围内; 2. 读/写分离 经典的数据库拆分方案,主库负责写,从库
我是本地Android开发者,我开始使用Flatter SDK。我开发了一个简单的应用程序,遵循官方的颤振文件。但是我发现调试应用的大小是46MB,对于这个简单的应用来说太大了。有没有办法优化应用程序的大小?因为Flatter应用程序的大小比原生Android应用程序大。
这样一堆 if 合理吗?后面还会加判断,会更多。 再拆分的话感觉不太好,有更好的方法吗?
给定一个正负整数数组,如何找到长度在和之间的最大和子数组(连续子数组)? 例如:如果数组是 我的方法: 我不太确定如何处理这个问题。我想也许是滑动窗口+Kadane的组合。我听说前缀和+滑动窗口可能是一个可能的解决方案,但我不确定如何实现它。
主要内容:业务场景,如何通过缓存优化查询接口,基于大数据离线平台进行缓存预热,本地缓存框架:Ehcache今天给大家来分享一个知识,那就是平时我们开发系统的时候,如何运用 Ehcache 这款本地缓存框架,把我们的查询性能大幅度提升优化,甚至让很多查询操作性能提升到 100 倍以上,下面就来讲讲这个话题。 业务场景 首先给大家引入一个场景,就是假设咱们写的一套 Java 系统要跑一个几百行的大 SQL 从 MySQL 里查询数据,这个查询是不是会速度非常的慢? 那肯定是了,这种几百行大 SQL
我有这样两个数组需要循环匹配出结果,如果没有用splice,出来的结果是正确的。但是我想优化下循环查找的代码,发现结果不对了 后来我又试了下splice函数 发现果然结果和我预想的不同了 请问上面的代码我该如何降低每次的循环量?