簡體   English   中英

JavaScript中的整數和小數運算速度

[英]interger and decimal operation speed in JavaScript

這是我測試過的代碼。

  (function() { var i, x; console.time('a'); for (i = x = 0; i < 1000000; x++) { if (x > 1000) { i++; x = 0; } } console.timeEnd('a'); console.time('b'); for (i = x = 0; i < 1000000; x += 0.001) { if (x > 1) { i++; x = 0; } } console.timeEnd('b'); })(); var i, x; console.time('c'); for (i = x = 0; i < 1000000; x++) { if (x > 1000) { i++; x = 0; } } console.timeEnd('c'); console.time('d'); for (i = x = 0; i < 1000000; x += 0.001) { if (x > 1) { i++; x = 0; } } console.timeEnd('d'); 

其結果如下。 a是1200毫秒。 b是1200毫秒。 c是2300毫秒。 d是23000毫秒。

a和b在操作速度上沒有差異。 (即使您增加操作次數)

但..

c和d的運算速度相差十倍!!!

(a和c),(b和d)彼此相同的代碼。

區別在於a和b指局部變量,c和d指全局變量。

因此,可以理解根據搜索范圍的速度差。

(a比c快,因為搜索范圍更窄!)

但是我無法理解“整數與小數”運算速度的差異。

這是為什么〜?

為什么“ a vs b”沒有速度差異,“ c vs d”速度是否不同?

這個問題讓我太累了。 請幫我。 T ^ T

我做了很多搜索來解決此問題,但是我無法解決。 下面的鏈接是我查看過的眾多答案之一。

為什么使用window.variable訪問變量的速度較慢?

答案被其作者刪除,因此我也發表了意見。 所以這是我發現的:

編輯

我糾正了我的愚蠢(我希望。@ Bergi會讓我保持直覺)。 重新設計了實驗,以下是修改的注釋。 范圍似乎是問題所在。 使用全局范圍的變量運行較慢,使用本地范圍的變量運行較快。

結束編輯

我認為問題在於解決全局范圍和/或范圍層次結構中的變量。

實驗:

  • 在IIFE(“ a”和“ b”)中注釋掉var i,x聲明
  • 將“ d”轉換為構造函數。 實例化一個新對象。

Chrome中的結果:

  • “ a”的運行速度似乎慢了50%。
  • b”的運行速度與原始“ d”一樣慢
  • 作為對象“ d”的運行速度要快得多,達到5-8倍。

筆記:

  • 在Chrome和SO摘要運行程序中,相對結果更加引人注目

  • 原始“ d”和對象“ d”在SO摘要運行程序中的運行幾乎相同。 有趣。

  (function() { // var i, x; console.time('a'); for (i = x = 0; i < 1000000; x++) { if (x > 1000) { i++; x = 0; } } console.timeEnd('a'); console.time('b'); for (i = x = 0; i < 1000000; x += 0.001) { if (x > 1) { i++; x = 0; } } console.timeEnd('b'); })(); var i, x; console.time('c'); for (i = x = 0; i < 1000000; x++) { if (x > 1000) { i++; x = 0; } } console.timeEnd('c'); console.time('d'); for (i = x = 0; i < 1000000; x += 0.001) { if (x > 1) { i++; x = 0; } } console.timeEnd('d'); function sloePoke() { this.q, this.r, this.go = function() { console.time('d'); for (this.q = this.r = 0; this.q < 1000000; this.r += 0.001) { if (this.r > 1) { this.q++; this.r = 0; } } console.timeEnd('d'); } } var sloth = new sloePoke(); sloth.go(); 

很難確定確切原因,但是可以觀察到一些事情。

首先,對於范圍內的示例, x可能會被丟棄,從而使該計算至少沒有意義。 通過優化很容易看到x永遠不會使用,因此無需評估它。

對於第二個示例,十進制與整數不會引起差異。 例如,您可以嘗試使用x+=7 ,並且會有類似的延遲。

 console.time('d'); for (i = 0, x = 0; i < 1000000000; x+=7 ) { i++; }; console.timeEnd('d') 

如果初始x值較高,則相同:

 console.time('d'); for (i = 0, x = 10000000000; i < 1000000000; x+=1 ) { i++; }; console.timeEnd('d') 

玩數字,我們可以嘗試找到臨界點。 讓我們使用Math.pow嘗試查找時間在哪里變化。 您會發現它在Math.pow(2, 30) Math.pow(2, 31) Math.pow(2, 30)Math.pow(2, 31) Math.pow(2, 30)之間發生了巨大變化。 嘗試:

 console.time('c'); for (i = 0, x = Math.pow(2, 30); i < 1000000000; x+=1 ) { i++; }; console.timeEnd('c'); console.time('d'); for (i = 0, x = Math.pow(2, 31); i < 1000000000; x+=1 ) { i++; };console.timeEnd('d') 

因此,由此可以用single-precision formatdouble-precision format之間的差異來解釋。 Math.pow(2,31)是單精度格式的限制(請參閱: https : //en.wikipedia.org/wiki/Single-precision_floating-point_format )。 盡管在javascript中, Numbers被認為是雙single-precision ,但沒有什么可以說的是引擎沒有進行優化,以便在可能的情況下使用single-precision 也很高興看到,當您自己添加0.001時會發生什么。 很快,它提供了一些需要雙精度的東西。 看到:

 console.log(0.001 + 0.001 + 0.001 + 0.001 +0.001 + 0.001 + 0.001 + 0.001+0.001 + 0.001 + 0.001) 

同樣,很難說這是確切的原因,但是推動這種推理的一種方法是從Math.pow(2, 31) - 1000000000 2,31)-1000000000(這意味着您將整個時間都停留在單個謂詞中)開始並遞增看看時間如何演變。 讓我們增加10000000,以便有一些有意義的東西。 這給了我這張桌子:

x starts at 1147483648: 2861s
x starts at 1157483648: 3100s
x starts at 1167483648: 3537s
x starts at 1177483648: 3366s
x starts at 1187483648: 3656s
x starts at 1197483648: 3916s
x starts at 1207483648: 4257s
x starts at 1217483648: 4537s
x starts at 1227483648: 4587s
x starts at 1237483648: 4798s
x starts at 1247483648: 4910s
x starts at 1257483648  5200s
x starts at 1267483648: 5364s

似乎線性增加。 如果嘗試遞減,您會發現時間並沒有改變(當然,時間也取決於其他因素,但是一般來說,這至少是我得到的結果)。

因此,基於此,示例中時間的差異似乎是基於可能時使用單精度的javascript引擎,從而加快了計算速度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM