C# 大型電商項目效能最佳化(一)

來源:互聯網
上載者:User

標籤:

經過幾個月的忙碌,我廠最近的電商平台項目終於上線,期間遇到的問題以及解決方案,也可以拿來和大家多做交流了。

我廠的項目大多採用C#.net,使用逐漸發展併流行起來的EF(Entity Framework)架構,並搭配使用丹麥的一款主打CMS, DMS的.net web應用程式sitecore。

本篇為基礎篇,側重於闡述編碼規範和一些編碼技巧對系統效能的影響。不規範的編碼方式,可能對單個方法或模組產生的效能影響是微不足道的,但在大型電商項目中,高並發的情境隨處可見,欠妥的編碼方式,可能會對整個系統的效能及使用者體驗,造成很大的影響。

作為電商項目,對效能影響最明顯的模組,莫過於下訂單及修改庫存。在高並發情境下,這些模組的資料庫存取的效能要求是非常高的,少許的效能浪費,都可能使系統在使用中的表現差強人意。

首先,我們來闡述一下EF架構下得編碼規範。這裡我們可以參考msdn關於IQueryable<T>及IEnumerable<T>的介紹:

對於在記憶體中集合上啟動並執行方法(即擴充 IEnumerable< T> 的那些方法),返回的可枚舉對象將捕獲傳遞到方法的參數。在枚舉該對象時,將使用查詢運算子的邏輯,並返回查詢結果。

與之相反,擴充 IQueryable <T> 的方法不會實現任何查詢行為,但會產生一個表示要執行的查詢的運算式樹狀架構。查詢處理由源 IQueryable<T> 對象處理。

 

IQueryable<T>會產生一個查詢運算式樹,並不會將資料直接取出來,但該對象的擴充方法為我們提供了大量的高效協助工具功能,例如判斷資料是否存在的Any(),查詢資料數量的Count(),統計計數屬性的Sum()等,EF會協助我們產生最優的sql,以減少資料庫存取時的效能損耗。這些方法,我們都可以用比較笨拙的編碼方式進行實現,但其效率會低很多。

另外,編碼過程中應儘可能避免使用ToList()方法及GetById()方法,這裡依舊可以參考msdn,但筆者可以直白地去描述:採用這兩種方法後,程式會直接將資料從資料庫中讀取出來,並載入到記憶體,接下來我們可以直接操作這些實實在在的資料,並使用List<T>所擴充的方法。然而這種方案會造成以下效能問題:

1.將未經業務處理的運算式樹狀架構直接用來查詢資料,其資料量太大,資料庫的存取,磁碟的IO,都需要消耗大量的時間和空間。

2.EF支援的導覽屬性,會將相關聯的對象都查出來,屆時龐大的資料又擁有更龐大的分支,讓記憶體和CPU飆升。

為了避免上述問題,EF為我們提供了行之有效方法:

1.查詢初期少用ToList()及GetDtoById()方法。

2.查詢過程中,使用Select()和SelectMany()方法,只選取自己所需要的屬性或對象。

 

為了看出不規範的編碼方式帶來的效能損耗,我們來看一段例子比較:

1.以下是只選取自己所需的屬性的代碼:

var productSKU = unitOfWork.ProductSku.Get(p => p.Id == item.SKUId)
  .Select(p => new { p.Id, p.ProductId, p.Product })
  .FirstOrDefault();

提交訂單耗時的:

2.採用GetById()方法:

var productSKU = unitOfWork.ProductSku.GetByID(item.SKUId);

提交訂單耗時:

筆者電腦老舊,該資料在i5 8G ram的電腦中僅需要200ms的時間長度,在效能更強的伺服器上耗時更短。

從對比中我們可以看到:僅僅只修改了一個方法,程式請求的耗時竟有將近一倍的誤差!如果我們的代碼中充斥著這種懶惰的不規範寫法,在高並發情境下,系統會被拖得很慢,甚至會出現程式報錯。

 

接下來,我們說下拋開EF架構的做法,擅長sql編程的園友,可能會不屑EF的提供的各種方案,直接寫sql,採用ADO不是更快嗎?的確,直接運行sql會讓程式更快,ADO的速度是大家所認可的。EF也支援大家使用直接編寫sql的方式:

var productSKU = dbContext.Database.SqlQuery<ProductSku>(sqlStr);

如果sql編程功力深厚,筆者是非常支援這種編程方案的。但EF架構也有其天生的優勢:

1.EF架構讓更多的初級軟體從業者更快地學習和編寫程式

2.EF提供的完善的擴充方法,協助軟體從業人員實現各種功能

3.規範編寫的EF C#代碼,並不會比原生的sql慢太多

 

這讓筆者想起C#.net與Java程式員之間的矛盾^_^。筆者因為機緣巧合,也寫過一段時間的Java。

二者的設計理念確實有所不同:

1.C#.net讓初學者更快地入門,提供了更多的類庫和方法,其出色的IDE讓編程人員省心省力。且C#.net已經開源。

2.Java則需要編程人員做更多的思考,自己配置環境變數,自己敲命令列,讓編程人員在思考的過程中加深對電腦原理、作業系統和軟體工程的認識。

毫無疑問:兩者都是當代最出色的進階程式語言(PHP,Python,JavaScript等的同行勿噴^_^)與其花時間爭論誰才是最好的語言,不如兼而學之。

以上是本次效能最佳化介紹的基礎篇,後續會為大家帶來資料庫層面的最佳化經驗及體會。

C# 大型電商項目效能最佳化(一)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.