2009-05-20 44 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(); 
      } 
     } 
    } 
}