【发布时间】:2016-07-06 16:47:50
【问题描述】:
我面临的挑战本质上是:给定一个数字数组作为输入,在 j input[j] 的情况下,找出任意两个数字之间的最大差。
我写了两个解决方案,一个是蛮力双嵌套循环,另一个是我尝试优化它。它们如下:
// Brute Force Method
function findGreatestDiffV1(nums) {
let start = new Date().getTime();
let greatestDiff = 0;
for (let i = 1; i < nums.length; i++) {
for (let j = 0; j < i; j++) {
let diff = nums[i] - nums[j];
if (diff > greatestDiff) greatestDiff = diff;
}
}
console.log(((new Date().getTime() - start) / 1000.0) + " Seconds");
return greatestDiff;
}
// Optimized method
function findGreatestDiffV2(nums) {
let start = new Date().getTime();
let smallestNum = nums[0];
let greatestDiff = 0;
for (let i = 1; i < nums.length; i++) {
if (nums[i] < smallestNum) smallestNum = nums[i];
if ((nums[i] - smallestNum) < greatestDiff) continue;
for (let j = 0; j < i; j++) {
let diff = nums[i] - nums[j];
if (diff > greatestDiff) greatestDiff = diff;
}
}
console.log(((new Date().getTime() - start) / 1000.0) + " Seconds");
return greatestDiff;
}
这些工作正常,并且输出正确的结果以及预期的运行时间,即对于较大数据集的 V2 显着降低。
然后我将它们修改为只返回运行时间:
function findGreatestDiffV1Time(nums) {
let start = new Date().getTime();
let greatestDiff = 0;
for (let i = 1; i < nums.length; i++) {
for (let j = 0; j < i; j++) {
let diff = nums[i] - nums[j];
if (diff > greatestDiff) greatestDiff = diff;
}
}
return ((new Date().getTime() - start) / 1000.0);
}
function findGreatestDiffV2Time(nums) {
let start = new Date().getTime();
let smallestNum = nums[0];
let greatestDiff = 0;
for (let i = 1; i < nums.length; i++) {
if (nums[i] < smallestNum) smallestNum = nums[i];
if ((nums[i] - smallestNum) < greatestDiff) continue;
for (let j = 0; j < i; j++) {
let diff = nums[i] - nums[j];
if (diff > greatestDiff) greatestDiff = diff;
}
}
return ((new Date().getTime() - start) / 1000.0);
}
我创建了这个辅助函数,它生成长度为 numOfDiffs 和最大个体数 maxDiff 的输入:
function generateDiffs(numOfDiffs, maxDiff) {
let diffs = [];
for (let i = 0; i < numOfDiffs; i++) {
diffs.push(Math.floor(Math.random() * maxDiff));
}
return diffs;
}
但是,这就是事情出问题的地方,我不知道为什么。
当使用仅返回运行时的版本时,无论输入的大小如何,V1 的时间都为 0。 V2 正在返回任何大小集的正确时间,但 V1 几乎立即继续逃逸并返回 0。
最可能的问题是我在某处有一个明显的错误,但我想知道这是否可能是对 JavaScript 如何执行某些功能的一些误解,甚至是某处的范围溢出。但无论如何,我找不到它,这让我发疯。
【问题讨论】:
-
我怀疑 Javascript 编译器已经注意到你在循环之后从不使用任何变量,所以它优化了整个循环。
-
我不确定为什么 V2 不会发生这种情况,可能循环太复杂而无法分析。
-
尝试更改它们以返回包含最大差异和时间的对象。
-
您可以使用
performance.now进行计时。 -
非常有趣。无论你在哪里运行它都会这样做吗?我无法在我的任何浏览器中重现:jsfiddle.net/b0dm98ds
标签: javascript debugging time