Какой кусок кода более производительный? - PullRequest
4 голосов
/ 20 мая 2009

У меня есть код, который я открываю, который используется для преобразования текста в 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 пользователя, чтобы мы могли сгенерировать его граватар-URL Таким образом, представление может вызывать этот метод несколько десятков раз.

Не пытаясь тратить слишком много времени на стресс преждевременную оптимизацию и т. Д ... что будет лучше?

Ответы [ 4 ]

10 голосов
/ 20 мая 2009

Я бы больше интересовался поточно-ориентированным ... MSDN не говорит (если я его пропустил), что MD5CryptoServiceProvider является поточно-ориентированным, поэтому IMO лучший вариант - иметь по одному на вызов. .

Неважно, как быстро вы можете получить неправильный ответ; -p

То, что вы, вероятно, не хотите сделать (чтобы исправить проблему с безопасностью потоков) - это иметь статический экземпляр и lock вокруг него ... который сериализует весь ваш криптографический код, когда он может работать параллельно на разных запросах.

4 голосов
/ 20 мая 2009

Проверьте и оцените время. Первый более производительный, но, вероятно, не имеет значения.

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();
            }
        }
    }
}
3 голосов
/ 20 мая 2009

Существующий код, как я ожидаю, будет немного более быстрым, поскольку он экономит при реконструкции MD5CryptoServiceProvider при каждом вызове, но я также ожидаю, что время будет зависеть от вызова ComputeHash ().

2 голосов
/ 20 мая 2009

Я лично не понимаю, почему это так или иначе имеет значение, подумайте о порче другого кода, который должен запускаться только для генерации страницы. Это шесть из полутора десятков других, экономия в любом случае будет крошечной.

...