成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Lambda表達式:要性能還是要清晰的代碼?

開發 后端
本文分析了Lambda表達式實現序列的兩種寫法,并建議與其過早的考慮代碼性能,還是代碼的清晰更加重要。

在上文的***個示例中,我們演示了如何使用Lambda表達式配合.NET 3.5中定義的擴展方法來方便地處理集合中的元素(篩選,轉化等等)。不過有朋友可能會提出,那個“普通寫法”并非是性能***的實現方法。方便起見,也為了突出“性能”方面的問題,我們把原來的要求簡化一下:將序列中的偶數平方輸出為一個列表。按照那種“普通寫法”可能就是:

  1. static List< int> EvenSquare(IEnumerable< int> source)  
  2. {  
  3.     var evenList = new List< int>();  
  4.     foreach (var i in source)  
  5.     {  
  6.         if (i % 2 == 0) evenList.Add(i);  
  7.     }  
  8.  
  9.     var squareList = new List< int>();  
  10.     foreach (var i in evenList) squareList.Add(i * i);  
  11.  
  12.     return squareList;  
  13. }  
  14.  

從理論上來說,這樣的寫法的確比以下的做法在性能要差一些:

  1. static List< int> EvenSquareFast(IEnumerable< int> source)  
  2. {  
  3.     List< int> result = new List< int>();  
  4.     foreach (var i in source)  
  5.     {  
  6.         if (i % 2 == 0) result.Add(i * i);  
  7.     }  
  8.  
  9.     return result;  
  10. }  
  11.  

在第二種寫法直接在一次遍歷中進行篩選,并且直接轉化。而***種寫法會則根據“功能描述”將做法分為兩步,先篩選后轉化,并使用一個臨時列表進行保存。在向臨時列表中添加元素的時候,List< int>可能會在容量不夠的時候加倍并復制元素,這便造成了性能損失。雖然我們通過“分析”可以得出結論,不過實際結果還是使用CodeTimer來測試一番比較妥當:

  1. List< int> source = new List< int>();  
  2. for (var i = 0; i <  10000; i++) source.Add(i);  
  3.  
  4. // 預熱  
  5. EvenSquare(source);  
  6. EvenSquareFast(source);  
  7.  
  8. CodeTimer.Initialize();  
  9. CodeTimer.Time("Normal", 10000, () => EvenSquare(source));  
  10. CodeTimer.Time("Fast", 10000, () => EvenSquareFast(source));  
  11.  

我們準備了一個長度為10000的列表,并使用EvenSquare和EvenSquareFast各執行一萬次,結果如下:

  1. Normal  
  2.         Time Elapsed:   3,506ms  
  3.         CPU Cycles:     6,713,448,335  
  4.         Gen 0:          624  
  5.         Gen 1:          1  
  6.         Gen 2:          0  
  7.  
  8. Fast  
  9.         Time Elapsed:   2,283ms  
  10.         CPU Cycles:     4,390,611,247  
  11.         Gen 0:          312  
  12.         Gen 1:          0  
  13.         Gen 2:          0  

Lambda表達式的執行:性能比對與結論

結果同我們料想中的一致,EvenSquareFast無論從性能還是GC上都領先于EvenSquare方法。不過,在實際情況下,我們該選擇哪種做法呢?如果是我的話,我會傾向于選擇EvenSquare,理由是“清晰”二字。

EvenSquare雖然使用了額外的臨時容器來保存中間結果(因此造成了性能和GC上的損失),但是它的邏輯和我們需要的功能較為匹配,我們可以很容易地看清代碼所表達的含義。至于其中造成的性能損失在實際項目中可以說是微乎其微的。因為實際上我們的大部分性能是消耗在每個步驟的功能上,例如每次Int32.Parse所消耗的時間便是一個簡單乘法的幾十甚至幾百倍。因此,雖然我們的測試體現了超過50%的性能差距,不過由于這只是“純遍歷”所消耗的時間,因此如果算上每個步驟的耗時,性能差距可能就會變成10%,5%甚至更低。

當然,如果是如上述代碼那樣簡單的邏輯,則使用EvenSquareFast這樣的實現方式也沒有任何問題。事實上,我們也不必強求將所有步驟完全合并(即僅僅使用1次循環)或完全分開。我們可以在可讀性與性能之間尋求一種平衡,例如將5個步驟使用兩次循環來完能是更合適的方式。

說到“分解循環”,其實這類似于Martin Fowler在他的重構網站所上列出的重構方式之一:“Split Loop”。雖然Split Loop和我們的場景略有不同,但是它也是為了代碼的可讀性而避免將多種邏輯放在一個循環內。將循環拆開之后,還可以配合“Extract Method”或“Replace Temp with Query”等方式實現進一步的重構。自然,它也提到拆分后的性能影響:

You often see loops that are doing two different things at once, because they can do that with one pass through a loop. Indeed most programmers would feel very uncomfortable with this refactoring as it forces you to execute the loop twice - which is double the work.

But like so many optimizations, doing two different things in one loop is less clear than doing them separately. It also causes problems for further refactoring as it introduces temps that get in the way of further refactorings. So while refactoring, don't be afraid to get rid of the loop. When you optimize, if the loop is slow that will show up and it would be right to slam the loops back together at that point. You may be surprised at how often the loop isn't a bottleneck, or how the later refactorings open up another, more powerful, optimization.

這段文字提到,當拆分之后,您可能會發現更好的優化方式。高德納爺爺也認為“過早優化是萬惡之源”。這些說法都在“鼓勵”我們將程序寫的更清晰而不是“看起來”更有效率。

以上便分析了使用C# Lambda表達式編碼時需要優先考慮代碼清晰度的理由。

【編輯推薦】

  1. .NET Lambda表達式的函數式特性:索引示例
  2. .NET Lambda表達式的語義:字符串列表范例
  3. 使用.NET 3.5 Lambda表達式實現委托
  4. 各版本.NET委托的寫法回顧
  5. C# Actor模型開發實例:網絡爬蟲
責任編輯:yangsai 來源: 老趙點滴
相關推薦

2012-06-26 10:03:58

JavaJava 8lambda

2009-09-11 09:48:27

Linq Lambda

2009-09-09 13:01:33

LINQ Lambda

2009-09-15 15:18:00

Linq Lambda

2022-12-05 09:31:51

接口lambda表達式

2024-03-25 13:46:12

C#Lambda編程

2009-08-27 09:44:59

C# Lambda表達

2009-09-15 17:30:00

Linq Lambda

2009-09-17 09:44:54

Linq Lambda

2009-09-17 10:40:22

Linq Lambda

2020-10-16 06:40:25

C++匿名函數

2021-11-10 09:45:06

Lambda表達式語言

2009-07-09 09:51:07

Lambda表達式C#

2009-08-27 09:57:50

C# Lambda表達

2009-08-31 17:11:37

Lambda表達式

2009-09-17 09:09:50

Lambda表達式Linq查詢

2009-08-26 16:17:23

C# Lambda表達

2017-12-07 14:23:55

前端Javascript正則表達式

2013-04-07 15:44:26

Java8Lambda

2009-08-10 09:41:07

.NET Lambda
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产激情视频网址 | 一级毛片免费看 | 国产精品久久久乱弄 | 日韩欧美三区 | 91精品国产一区二区 | 亚洲国产成人精品女人久久久 | 天天弄 | 久久精品欧美一区二区三区不卡 | 久久人人网 | 成人一区精品 | 999观看免费高清www | 亚洲成在线观看 | av资源在线看 | 欧美a级网站 | 伊人网站视频 | 国产精品久久国产精品 | 欧美成人hd | 欧美成人免费在线视频 | 不卡一二区| 中国一级特黄毛片大片 | 一级中国毛片 | 精品视频www | 91日韩 | 男人的天堂在线视频 | 欧美在线网站 | 在线啊v| 暖暖日本在线视频 | 伊人网站 | 国产精品高清在线 | 久久天堂网 | 久久69精品久久久久久久电影好 | 亚洲精品视频在线 | 99久久国产综合精品麻豆 | 九九热这里只有精品在线观看 | 一区二区三区在线播放 | 成人国产精品免费观看 | 精品国产青草久久久久96 | www久久 | 欧美a级成人淫片免费看 | 国产精品色av| 免费黄色av网站 |