目前我遇到了一个非常奇怪的性能问题。 SlowHeap所需的平均值为1448.623ms,而FastHeap仅需要550.425ms。我已多次看过它,但两者之间的唯一区别是第一个是使用" undefined" _arr开头的元素,第二个元素没有。但是,他们都做同样的操作,等等。我已经验证了下面的代码。
是否有人可以解决这个问题?
let slowHeapOperationCount = 0
let fastHeapOperationCount = 0
let slowHeapExchanged = []
let fastHeapExchanged = []
function SlowHeap(cmp = (a, b) => a > b ? 1 : a < b ? -1 : 0) {
this.cmp = cmp
this._arr = [undefined]
this.size = 0
}
function FastHeap(cmp = (a, b) => a > b ? 1 : a < b ? -1 : 0) {
this.cmp = cmp
this._arr = []
this.size = 0
}
SlowHeap.prototype.bubbleUp = function (cmp, _arr, val) {
let idxNr = this.size, parentIdxNr = idxNr >> 1
while (idxNr > 0 && cmp(_arr[parentIdxNr], val) > 0) {
slowHeapExchanged.push([_arr[parentIdxNr], val])
_arr[idxNr] = _arr[parentIdxNr]
_arr[parentIdxNr] = val
idxNr = parentIdxNr
parentIdxNr = idxNr >> 1
slowHeapOperationCount++
}
}
FastHeap.prototype.bubbleUp = function (cmp, _arr, val) {
var idxNr = this.size,
parentIdxNr = ((idxNr - 1) / 2) | 0;
while (idxNr > 0 && cmp(_arr[parentIdxNr], val) > 0) {
fastHeapExchanged.push([_arr[parentIdxNr], val])
_arr[idxNr] = _arr[parentIdxNr];
_arr[parentIdxNr] = val;
idxNr = parentIdxNr;
parentIdxNr = ((idxNr - 1) / 2) | 0;
fastHeapOperationCount++
}
}
SlowHeap.prototype.push = function (val) {
++this.size
this._arr.push(val)
this.bubbleUp(this.cmp, this._arr, val)
return this.size
}
FastHeap.prototype.push = function (val) {
this._arr.push(val);
this.bubbleUp(this.cmp, this._arr, val);
return ++this.size;
}
const itemCount = 4000000
const slowHeap = new SlowHeap()
const fastHeap = new FastHeap()
//
// Append the same Number Collection to each Heap:
const numberCollection = []
for (let idxNr = 0; idxNr < itemCount; idxNr++) numberCollection.push(Math.random())
//
// Benchmark for the Slow Heap:
console.time('SlowHeap')
for (let idxNr = 0; idxNr < itemCount; idxNr++) {
slowHeap.push(numberCollection[idxNr])
}
console.timeEnd('SlowHeap')
//
// Benchmark for the Fast Heap:
console.time('FastHeap')
for (let idxNr = 0; idxNr < itemCount; idxNr++) {
fastHeap.push(numberCollection[idxNr])
}
console.timeEnd('FastHeap')
//
// Verify the "_arr" from the Slow Heap against the Fast Heap:
for (let idxNr = 0; idxNr < itemCount; idxNr++) {
if (slowHeap._arr[idxNr + 1] !== fastHeap._arr[idxNr]) console.log('Unequal value found!')
}
if (slowHeapExchanged.length !== fastHeapExchanged.length) console.log('Help! Comp. is not equal.')
for (let idxNr = 0, maxNr = slowHeapExchanged.length; idxNr < maxNr; idxNr++) {
if (slowHeapExchanged[idxNr][0] !== fastHeapExchanged[idxNr][0] || slowHeapExchanged[idxNr][1] !== fastHeapExchanged[idxNr][1]) {
console.log('Help!')
}
}
console.log(slowHeapOperationCount)
console.log(fastHeapOperationCount)
答案 0 :(得分:2)
我对具体细节没有任何了解,但它看起来像是启用/禁用的V8优化:当您使用<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Resposive layout</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div id="header">
<h3> Header area </h3>
</div>
<div id="wrapper">
<div id="main1">
<div id="leftside">
<h3> Categories </h3>
</div>
<div id="middle">
<h3> Slider </h3>
</div>
<div id="rightside">
<h3> Mobile App </h3>
</div>
</div>
<br>
<div id="special_discount">
<div id="sp_dis_leftside">
<h3> Mega Discount box </h3>
</div>
<div id="sp_dis_middle">
<h3> Top Brands </h3>
</div>
<div id="sp_dis_rightside">
<h3> Crazy Discount </h3>
</div>
</div>
<br>
<div id="newsletter">
<h3>Subscribe to Newsletter</h3>
</div>
<br>
<div id="recommended">
<div id="recom_leftside">
<h3> Best for You </h3>
</div>
<div id="recom_rightside">
<h3> Recommended Products Manual Slider </h3>
</div>
</div>
<br>
<div id="ads1">
<h3>Single Product Ads to Buy</h3>
</div>
<br>
<div id="category1">
<div id="cat1_leftside">
<h3> Horizontal Slider Cat 1 </h3>
</div>
<div id="cat1_rightside">
<h3> </h3>
</div>
<div id="home_category1_boxes1">
<ol>
<h3>Men Dress</h3>
</ol>
<ol>Men Dress 1</ol>
<ol>Men Dress 2</ol>
<ol>Men Dress 3</ol>
<br>
<ol>
<h3>Men Accessories</h3>
</ol>
<ol>Men Accessories1</ol>
<ol>Men Accessories2</ol>
<ol>Men Accessories3</ol>
</div>
<div id="home_category1_boxes2"> <img src="images/boxes/cat1/big.jpg" width="376" height="350"></div>
<div id="home_category1_boxes3">
<img src="images/boxes/cat1/box1.jpg" width="140px" />
<img src="images/boxes/cat1/box2.jpg" width="140px" />
<img src="images/boxes/cat1/box3.jpg" width="140px" />
<img src="images/boxes/cat1/box4.jpg" width="140px" />
</div>
</div>
<br>
<div id="ads_worldwide">
<h3>Shopping Worldwide</h3>
</div>
<br>
<div id="category2">
<div id="cat2_leftside">
<h3> Horizontal Slider Cat 2 </h3>
</div>
<div id="cat2_rightside">
<h3> Category 2 Top Brans with 1 big pic and 4 box pics </h3>
</div>
</div>
<br>
<div id="ads2">
<h3>Single Product Ads to Buy</h3>
</div>
<br>
<div id="category3">
<div id="cat3_leftside">
<h3> Horizontal Slider Cat 3 </h3>
</div>
<div id="cat3_rightside">
<h3> Category 3 Top Brans with 1 big pic and 4 box pics </h3>
</div>
</div>
<br>
<div id="category4">
<div id="cat4_leftside">
<h3> Horizontal Slider Cat 4 </h3>
</div>
<div id="cat4_rightside">
<h3> Category 4 Top Brans with 1 big pic and 4 box pics </h3>
</div>
</div>
<br>
<div id="ads3">
<h3>Single Product Ads to Buy</h3>
</div>
<br>
<div id="category5">
<div id="cat5_leftside">
<h3> Horizontal Slider Cat 5 </h3>
</div>
<div id="cat5_rightside">
<h3> Category 5 Top Brans with 1 big pic and 4 box pics </h3>
</div>
</div>
<br>
<div id="category6">
<div id="cat6_leftside">
<h3> Horizontal Slider Cat 6 </h3>
</div>
<div id="cat6_rightside">
<h3> Category 6 Top Brans with 1 big pic and 4 box pics </h3>
</div>
</div>
<br>
<div id="ads4">
<h3>Single Product Ads to Buy</h3>
</div>
<br>
<div id="category7">
<div id="cat7_leftside">
<h3> Horizontal Slider Cat 7 </h3>
</div>
<div id="cat7_rightside">
<h3> Category 7 Top Brans with 1 big pic and 4 box pics </h3>
</div>
</div>
<br>
<div id="category8">
<div id="cat8_leftside">
<h3> Horizontal Slider Cat 8 </h3>
</div>
<div id="cat8_rightside">
<h3> Category 8 Top Brans with 1 big pic and 4 box pics </h3>
</div>
</div>
<br>
<div id="ads5">
<h3>Single Product Ads to Buy</h3>
</div>
<br>
<div id="category9">
<div id="cat9_leftside">
<h3> Horizontal Slider Cat 9 </h3>
</div>
<div id="cat9_rightside">
<h3> Category 9 Top Brans with 1 big pic and 4 box pics </h3>
</div>
</div>
<br>
<div id="category10">
<div id="cat10_leftside">
<h3> Horizontal Slider Cat 10 </h3>
</div>
<div id="cat10_rightside">
<h3> Category 10 Top Brans with 1 big pic and 4 box pics </h3>
</div>
</div>
<br>
<div id="footer">
</div>
</div>
</body>
</html>
替换undefined
时,0.0
不是那个慢了(事实上,对我来说它比SlowHeap
快)。
我的猜测是因为你用浮点数(FastHeap
)填充数组,只要数组包含所有相同类型的项目,就可以执行优化。
一旦引入类型不匹配(Math.random()
不是浮点数),V8可能不得不切换到更通用的数组类型,并放弃优化。