中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

在源碼階段寫出更快Ruby的秘訣

2018-07-20    來源:編程學(xué)習(xí)網(wǎng)

容器云強(qiáng)勢上線!快速搭建集群,上萬Linux鏡像隨意使用

優(yōu)化可以采取許多不同的形式,但程序員關(guān)注何處以及如何開發(fā)項(xiàng)目的過程中進(jìn)行優(yōu)化。這個(gè)講演來自RubyConf India 2015, 總部位于柏林的SoundCloud開發(fā)者Erik Michaels-Ober對于在源碼這個(gè)層級如何提升Ruby性能優(yōu)化,進(jìn)行了一次演講。

Michaels-Ober首先注意到的是,大多數(shù)開發(fā)人員對過早的性能優(yōu)化有偏見。他引用了斯坦福教授、算法設(shè)計(jì)和分析之父Donald Knuth,在1974年的一句話 "過早的優(yōu)化乃萬惡之源"。Michaels-Ober指出適當(dāng)?shù)牡缓蠒r(shí)宜的優(yōu)化的確會(huì)讓代碼“丑陋,難以閱讀和更復(fù)雜”,所以只有在必要或合時(shí)宜時(shí),進(jìn)行代碼優(yōu)化。

什么時(shí)候進(jìn)行優(yōu)化呢?這里,Michaels-Ober再次引用Knuth,他有兩個(gè)標(biāo)準(zhǔn):第一,優(yōu)化可以輕易獲得;第二,優(yōu)化的好處巨大(Knuth給出12%的閾值)。Michaels-Ober增加了第三個(gè)標(biāo)準(zhǔn),借用自 Ruby 的主設(shè)計(jì)者M(jìn)atz: Ruby為程序員快樂而生,所以優(yōu)化也應(yīng)使程序員感到快樂--不論是讓代碼更“漂亮”或擁有更好的性能。

優(yōu)化層次

Michaels-Ober接著概述了可能適用于任何語言和項(xiàng)目的不同層次的優(yōu)化:設(shè)計(jì)、源碼、構(gòu)建、編譯和運(yùn)行時(shí)。Michaels-Ober的重點(diǎn)是源碼優(yōu)化。再次搬出 Knuth ,大神認(rèn)為:“程序員的直覺預(yù)測電腦會(huì)如何解釋的代碼、是否優(yōu)化時(shí)會(huì)出現(xiàn)偏差”。 “對于代碼的快慢,我們沒有很好的直覺” Michaels-Ober說到。“我們常常犯錯(cuò),所以如果過早的優(yōu)化,或許你認(rèn)為你在優(yōu)化它,但實(shí)際上你在寫一個(gè)非最優(yōu)代碼”。

那么如果知道哪個(gè)版本是更優(yōu)的呢? “你必須跑個(gè)分”, Michaels-Ober 說到。Ruby內(nèi)置基準(zhǔn)測試庫允許對一個(gè)方法運(yùn)行指定的次數(shù)。然而Michaels-Ober指出內(nèi)置基準(zhǔn)測試的問題是你得猜運(yùn)行多少次才是明顯的提升。

作為替代,Michaels-Ober建議使用benchmark-ips(iteratorions per second), 它使用每秒鐘運(yùn)行次數(shù)而不是每次運(yùn)行秒數(shù)。每個(gè)版本的代碼運(yùn)行五秒,會(huì)生成一個(gè)代碼運(yùn)行次數(shù)的“報(bào)告”!5秒時(shí)間是一個(gè)足夠長的時(shí)間,足以移除統(tǒng)計(jì)誤差;運(yùn)行次數(shù)越多,誤差會(huì)越低,所以不必?fù)?dān)心這些誤差”。

在代碼階段寫出更快的 Ruby

Michaels-Ober接下來展示了一些如何簡化代碼來達(dá)到運(yùn)行更快、更易讀的例子(你可以參照Speaker Deck主題幻燈)。

Block vs. Symbol#to_proc

Symbol#to_pro比block快20倍,因?yàn)?Ruby 解釋器內(nèi)部做了優(yōu)化。Symbol#to_proc最初作為 RAILS 快捷方法,后來添加到了Ruby。Ruby知道如何運(yùn)行Symbol#to_proc,并在內(nèi)部進(jìn)行優(yōu)化。

Enumerable#map and Array#flatten vs. Enumerable#flat_map

map會(huì)返回一個(gè)列表的列表。如果想讓一個(gè)列表map然后再flatten,可以使用可讀性更好的flat_map代替map和flatten,倆工作方式相同,且flat_map快4.5倍,因?yàn)樗坏淮,而不是兩次?

Enumerable#reverse and Enumerable#each vs. Enumerable#reverse_each

reverse_each不會(huì)拷貝列表,只是反方向迭代。這使得它比另一種方法快 17%。

Hash#keys and Enumerable#each vs. Hash#each_key

Ruby 有個(gè)內(nèi)置方法創(chuàng)建哈希鍵列表。更快的方法是不立即創(chuàng)建列表,而只是返回鍵的值,這讓它快了33%。

Array#shuffle and Array#first vs. Array#sample

假設(shè)有個(gè)列表,想隨機(jī)的提取一些值。一個(gè)方法是使用array.shuffle.first,打亂列表然后取列表的第一個(gè)元素,或者使用array.sample,它比前一個(gè)方法快 15 倍。

Hash#merge vs. Hash#merge!

不可變版本修改哈希對比可變版本創(chuàng)建一個(gè)哈希的拷貝,再進(jìn)行合并和拷貝。因?yàn)樵诟〉目臻g內(nèi)修改哈希,所以快了 3 倍。同樣適用于Hash#[],快 2 倍速度。

Hash#fetch vs. Hash#fetch with block

fetch第二個(gè)參數(shù)是 block 要比直接傳遞 block 的結(jié)果快 2 倍。

String#gsub vs. String#sub

gsub將字符中所有的第一個(gè)字符替換成第二個(gè)字符。如果你只想進(jìn)行一次替換,也不掃描多余的字符。使用sub快 50%。

String#gsub vs. String#tr

想進(jìn)行全部替換時(shí),總是可以使用tr替代gsub,使用tr快 5 倍。

Parallel vs. sequential assignment

并行賦值需要分配列表,且可讀性不高。并行賦值在交換值的時(shí)候很有用,除此之外,使用順序賦值,它可讀性更好、快 40 %。

Throw/catch

與exceptions相比,使用throw/cath控制流跳轉(zhuǎn),它快5倍。

Michaels-Ober說到:“盡管其他的優(yōu)化可以在下一個(gè)代碼編譯階段完成,但上面這些源碼的優(yōu)化技術(shù)可以快速、無痛的完成,可以使 Ruby 代碼更快、性能更好、可讀性更高”。

標(biāo)簽: 代碼 開發(fā)者

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:app引導(dǎo)頁(背景圖片切換加各個(gè)頁面動(dòng)畫效果)

下一篇:不要和一種編程語言廝守終生:為工作正確選擇