2009-05-20 48 views
4

我有一些代碼,我正在revewing,它用於一些文字轉換爲MD5 Hash。很棒。它被用來創建一個的gravatar頭像MD5Hhash。它是: -哪一段代碼更高效?

static MD5CryptoServiceProvider md5CryptoServiceProvider = null; 

public static string ToMD5Hash(this string value) 
{ 
    //creating only when needed 
    if (md5CryptoServiceProvider == null) 
    { 
     md5CryptoServiceProvider = new MD5CryptoServiceProvider(); 
    } 

    byte[] newdata = Encoding.Default.GetBytes(value); 
    byte[] encrypted = md5CryptoServiceProvider.ComputeHash(newdata); 
    return BitConverter.ToString(encrypted).Replace("-", "").ToLower(); 
} 

請注意我們如何在第一次創建MD5CryptoServiceProvider這個方法被調用? (爲了簡單起見,不用擔心這裏的比賽條件)。

我想知道,是不是更昂貴的計算,如果我改變了用於創建提供的線,這...

using(var md5CryptoServiceProvider = new MD5CryptoServiceProvider()) 
{ 
    ... snip snip snip .... 
} 

現在,這是怎麼方法中使用/消費?那麼,想象這是StackOverflow的主頁 - >爲每個帖子生成用戶的md5哈希值,以便我們可以生成他們的gravatar url。所以這個視圖可能會調用這個方法幾十次。

,但不嘗試浪費太多時間在強調premature optimzation,等等...這將是更好?

回答

10

我會更感興趣的是線程安全...... MSDN不會(除非我錯過了)說MD5CryptoServiceProvider是線程安全的,所以IMO最好的選擇是每個調用一個...

不要緊,你很快就能得到錯誤的答案;-p

你可能做什麼不想做(固定線程安全問題)是有一個靜態實例, lock圍繞它......它會序列化所有的加密代碼,當它可以在不同的請求上並行運行時。

+0

因此,你建議他應用「使用」聲明,對吧? – Overhed 2009-05-20 15:06:16

3

現有的代碼我希望稍微快一點,因爲它可以節省每次調用時重建MD5CryptoServiceProvider的時間,但我也希望時間能夠被ComputeHash()的調用所控制。

2

我personnally看不出爲什麼會的問題無論哪種方式,考慮其他代碼綁紮有隻運行生成的頁面。其中六個一個,其他六個,這兩個方面的儲蓄都很小。

4

測試它和時間。第一個更高性能,但可能並不重要。

using System; 
using System.Diagnostics; 
using System.Security.Cryptography; 
using System.Text; 

namespace ConsoleApplication11 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Stopwatch timer=new Stopwatch(); 
      int iterations = 100000; 
      timer.Start(); 
      for (int i = 0; i < iterations; i++) 
      { 
       string s = "test" + i; 
       string t=s.ToMd5Hash0(); 
      } 
      timer.Stop(); 
      Console.WriteLine(timer.ElapsedTicks); 

      timer.Reset(); 
      timer.Start(); 
      for (int i = 0; i < iterations; i++) 
      { 
       string s = "test" + i; 
       string t = s.ToMd5Hash1(); 
      } 
      timer.Stop(); 
      Console.WriteLine(timer.ElapsedTicks); 

      Console.ReadKey(); 
     } 
    } 
    public static class Md5Factory 
    { 
     private static MD5CryptoServiceProvider md5CryptoServiceProvider; 
     public static string ToMd5Hash0(this string value) 
     { 
      if (md5CryptoServiceProvider == null) 
      { 
       md5CryptoServiceProvider = new MD5CryptoServiceProvider(); 
      } 
      byte[] newData = Encoding.Default.GetBytes(value); 
      byte[] encrypted = md5CryptoServiceProvider.ComputeHash(newData); 
      return BitConverter.ToString(encrypted).Replace("-", "").ToLower(); 
     } 
     public static string ToMd5Hash1(this string value) 
     { 
      using (var provider = new MD5CryptoServiceProvider()) 
      { 
       byte[] newData = Encoding.Default.GetBytes(value); 
       byte[] encrypted = provider.ComputeHash(newData); 
       return BitConverter.ToString(encrypted).Replace("-", "").ToLower(); 
      } 
     } 
    } 
}