哪一段代码更高效?

时间:2009-05-20 14:19:28

标签: c# .net optimization premature-optimization

我有一些我正在接受的代码,用于将一些文本转换为MD5 Hash。效果很好。它用于为重力头像创建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等......哪个更好?

4 个答案:

答案 0 :(得分:10)

我对线程安全更感兴趣... MSDN没有(除非我错过了)说MD5CryptoServiceProvider是线程安全的,所以IMO最好的选择是每次调用一个...

你得到错误答案的速度并不重要;-p

您可能想要做的事情(解决线程安全问题)是有一个静态实例,并且lock围绕它......这将序列化所有你的加密代码,它可以在不同的请求上并行运行。

答案 1 :(得分: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();
            }
        }
    }
}

答案 2 :(得分:3)

我希望现有的代码能够稍快一点,因为它可以节省每次调用时重建MD5CryptoServiceProvider的时间,但我也希望时间可以通过调用ComputeHash()来控制。

答案 3 :(得分:2)

我个人无法理解为什么它会对任何一种方式起作用,想想为了生成页面而必须运行的其他代码的绑定。它的六分之一和另外六分之一,这两种方式的节省都很小。