## 26.基準
基準是一種度量。 你可以測量代碼運行所需的時間。 所以,為什么這么重要? 隨著你成為更認真的編碼人員,完成一件工作就不再重要了。 重要的是你編寫代碼的程度以及代碼在實時環境中的性能。 你必須知道編寫快速運行的代碼。 要檢查你的代碼片段是否比其他代碼片段更快,可以使用基準測試。
以下面的示例為例,輸入并運行
```rb
# benchmark.rb
require 'benchmark'
Benchmark.bm do|b|
b.report("+= ") do
a = ""
1_000_000.times { a += "." }
end
b.report("<< ") do
a = ""
1_000_000.times { a << "." }
end
end
```
輸出量
```rb
user system total real
+= 55.030000 7.320000 62.350000 ( 62.303848)
<< 0.160000 0.000000 0.160000 ( 0.168452)
```
因此,讓我遍歷代碼,在`require 'benchmark'`行中,基準測試庫作為 Ruby 標準發行版的一部分包含在內,因此你可以要求此代碼在文件中不必大驚小怪。
現在讓我們看一下這個塊
```rb
Benchmark.bm do|b|
………….
end
```
它有什么作用? 首先,我們在`Benchmark`類中調用名為`bm`的函數,并在`do`和`end`之間傳遞一個塊。 現在,讓我們看看該塊中的內容
```rb
Benchmark.bm do|b|
b.report("+= ") do
a = ""
1_000_000.times { a += "." }
end
b.report("<< ") do
a = ""
1_000_000.times { a << "." }
end
end
```
參見上面的代碼。 我們正在使用`b.report("+= ")`準備報告,可以將將在輸出中打印的任何字符串傳遞給報告函數。 如果查看輸出的第二行`+= 55.030000 7.320000 62.350000 ( 62.303848)`,則會打印`+=`,因為`“+=”`已傳遞到`b.report()`。
`b.report()``打開一個代碼塊,你可以將任何需要基準標記的內容傳遞給該代碼塊。 在這里,我們傳遞了如下所示的代碼片段
```rb
b.report("+= ") do
a = ""
1_000_000.times { a += "." }
end
```
因此,我們為 a 分配了一個空字符串,并使用`+=`運算符對其添加了一百萬次。 我們得到這個
```rb
user system total real
+= 55.030000 7.320000 62.350000 ( 62.303848)
```
輸出顯示總共花費 62.35 秒,這是非常安靜的。 現在讓我們來看看第二個塊
```rb
b.report("<< ") do
a = ""
1_000_000.times { a << "." }
end
```
在這里,我們執行的操作與第一個相同,但是我們使用`<<`運算符而不是`+=`,這將產生以下輸出,如下所示
```rb
user system total real
+= 55.030000 7.320000 62.350000 ( 62.303848)
<< 0.160000 0.000000 0.160000 ( 0.168452)
```
因此,使用`<<`僅需 0.1685 秒,因此在字符串連接方面,`<<`遠優于`+=`。
現在,讓我們看看其他內容。 你們都知道計算機有內存。 當程序運行時,它需要記住事情并消耗一些內存,有時當可用內存變少時,Ruby 解釋器將清理內存。 這稱為垃圾收集 <sup class="footnote">[ [62](#_footnotedef_62 "View footnote.") ]</sup> 。 就像你的城市或市政當局收集垃圾一樣,城市運行正常。 現在想想,如果不收集垃圾,而你遇到的垃圾會流到街道上,整個城市步履蹣跚,事情真的會變慢,那將會發生什么。 同樣,如果程序運行足夠長的時間可以更好地收集垃圾,否則,運行的新代碼可能會變慢,并且如果對它進行基準測試,則可能會顯示錯誤的結果。
現在,在文本編輯器中鍵入以下程序并運行它。
```rb
# benchmark_2.rb
require 'benchmark'
puts "Testing without cleaning up"
Benchmark.bm do|b|
b.report("+=") do
a = ""
100_000.times { a += "." }
end
b.report("<<") do
a = ""
1_000_000.times { a << "." }
end
end
GC.start
puts
puts "Testing with cleaning up"
Benchmark.bmbm do|b|
b.report("+=") do
a = ""
100_000.times { a += "." }
end
b.report("<<") do
a = ""
100_000.times { a << "." }
end
end
```
Output
```rb
Testing without cleaning up
user system total real
+= 0.550000 0.220000 0.770000 ( 0.773730)
<< 0.150000 0.010000 0.160000 ( 0.159381)
Testing with cleaning up
Rehearsal --------------------------------------
+= 0.520000 0.180000 0.700000 ( 0.687914)
<< 0.010000 0.010000 0.020000 ( 0.018958)
----------------------------- total: 0.720000sec
user system total real
+= 0.530000 0.120000 0.650000 ( 0.650013)
<< 0.010000 0.000000 0.010000 ( 0.015668)
```
如果你看到此代碼產生的第一個基準測試
```rb
puts "Testing without cleaning up"
Benchmark.bm do|b|
b.report("+=") do
a = ""
100_000.times { a += "." }
end
b.report("<<") do
a = ""
1_000_000.times { a << "." }
end
end
```
在此,我們使用`Benchmark.bm`并像往常一樣運行它,它將生成以下輸出:
```rb
Testing without cleaning up
user system total real
+= 0.550000 0.220000 0.770000 ( 0.773730)
<< 0.150000 0.010000 0.160000 ( 0.159381)
```
基準總計分別為 0.77 和 0.16 秒。 在此塊之后,我們有這些行
```rb
GC.start
puts
```
在這些行中,我們正在收集垃圾或釋放該程序已使用的內存。 現在我們運行另一個由該代碼塊定義的基準
```rb
puts "Testing with cleaning up"
Benchmark.bmbm do|b|
b.report("+=") do
a = ""
100_000.times { a += "." }
end
b.report("<<") do
a = ""
100_000.times { a << "." }
end
end
```
那么`Benchmark.bmbm`的作用是什么? 直到這次我們使用`Benchmark.bm`! 在上述代碼中,我們有兩個基準正在運行。 `bmbm`確保在完成第一個基準測試之后,進行垃圾回收并釋放內存,以便下一個工作在垃圾回收環境中運行,從而獲得更好的準確結果。 這是第二個此代碼生成的輸出
```rb
Testing with cleaning up
Rehearsal --------------------------------------
+= 0.520000 0.180000 0.700000 ( 0.687914)
<< 0.010000 0.010000 0.020000 ( 0.018958)
----------------------------- total: 0.720000sec
```
如果你可以比較不帶 GC 的`100_000.times { a << "." }`的輸出和帶 GC 的`100_000.times { a << "." }`的輸出,分別為 0.16 秒和 0.02 秒。 現在,我想你會意識到垃圾收集的需要,無論是在城市中還是在編程中。
- 前言
- 紅寶石
- 先決條件
- 1.安裝 Ruby
- 2.在線資源
- 3.入門
- 4.比較與邏輯
- 5.循環
- 6.數組
- 7.哈希和符號
- 8.范圍
- 9.功能
- 10.可變范圍
- 11.類&對象
- 12.安全導航
- 13.打破大型程序
- 14.結構和 OpenStruct
- 15. Rdoc
- 16. Ruby 樣式指南
- 17.模塊和混入
- 18.日期和時間
- 19.文件
- 20. Proc,Lambda 和塊
- 21.多線程
- 22.異常處理
- 23.正則表達式
- 24.寶石
- 25.元編程
- 26.基準
- 27.測試驅動開發
- 28.觀察者模式
- 29.模板模式
- 30.工廠模式
- 31.裝飾圖案
- 32.適配器模式
- 33.單例模式
- 34.復合模式
- 35.建造者模式
- 36.策略模式
- 贊助商
- 捐
- 人們怎么說
- 版權
- 取得這本書