ASP.NET: производительность HttpModule - PullRequest
2 голосов
/ 17 ноября 2009

Я реализовал HttpModule, который перехватывает поток Response каждого запроса и запускает от полдюжины до десятка Regex.Replace () для каждого ответа text / html. Я обеспокоен тем, как много хита в исполнении я понесу здесь. Какой хороший способ узнать? Я хочу сравнить скорость с этим модулем HttpModule и без него.

Ответы [ 4 ]

2 голосов
/ 17 ноября 2009

У меня есть несколько таких, которые подключаются к конвейеру потока Response.Filter для обеспечения интеграции файлов ресурсов, упаковки JS / CSS и перезаписи статических файлов в абсолютные пути.

Пока вы проверяете свои регулярные выражения в RegexBuddy на скорость более нескольких миллионов итераций, убедитесь, что вы используете RegexOptions.Compiled, и помните, что часто самым быстрым и эффективным методом является использование регулярного выражения для широкой идентификации совпадений, а затем использование C # отточить это именно к тому, что вам нужно.

Убедитесь, что вы также кэшируете и конфигурируете, на которые вы полагаетесь.

У нас был большой успех с этим.

1 голос
/ 17 ноября 2009

Вот несколько идей:

  1. Добавьте некоторые счетчики производительности Windows и используйте их для измерения и представления данных о среднем времени. Вы также можете увеличить счетчик, только если измерение времени превышает определенный порог. и
  2. Используйте трассировку в сочетании с трассировкой Failed Request для сбора и представления данных о времени. Отчеты FRT также можно запускать, только если время выполнения страницы превышает пороговое значение.
  3. Напишите модульный тест, который использует часы ОС Windows для измерения того, сколько времени занимает выполнение кода.
  4. Добавьте флаг к своему коду, который можно включить или отключить на тестовой странице, чтобы включить или отключить код регулярного выражения, чтобы облегчить A / B-тестирование.
  5. Используйте инструмент нагрузочного тестирования, такой как WCAT, чтобы увидеть, сколько запросов страницы в секунду вы можете обрабатывать с включенным кодом и без него.
1 голос
/ 17 ноября 2009

Модуль Http - это просто обычный фрагмент кода, поэтому вы можете измерить время выполнения этого конкретного элемента замены регулярного выражения Достаточно. Имейте в качестве входных данных вашего стресс-теста набор типичных потоков ответов и измеряйте выполнение замены, используя класс Stopwatch Также рассмотрим переключатель RegexOptions.Compiled.

0 голосов
/ 05 декабря 2014

Недавно мне пришлось выполнить несколько тестов pef на HTTPModule, который я написал, и решил выполнить пару нагрузочных тестов для имитации веб-трафика и получения данных о производительности с настроенным модулем и без него. Это был единственный способ понять, как установлен модуль.

Я бы обычно что-то делал с Apache Bench (см. Следующую информацию о том, как intsall, Как установить apache bench на windows 7? ), но мне также пришлось использовать проверку подлинности Windows. Так как ab имеет только базовую аутентификацию, это не подходит для меня. ab гладко и учитывает различные сценарии запроса, так что это будет первое место для поиска. Еще одна мысль, что вы можете получить большую видимость, используя glimpse .

Из-за того, что я не мог использовать ab, я написал что-то нестандартное, что позволит выполнять параллельные запросы и тестировать разные времена URL.

Ниже приведен пример тестирования модуля, надеюсь, это поможет!

// https://www.nuget.org/packages/RestSharp
using RestSharp;
using RestSharp.Authenticators;
using RestSharp.Authenticators.OAuth;
using RestSharp.Contrib;
using RestSharp.Deserializers;
using RestSharp.Extensions;
using RestSharp.Serializers;
using RestSharp.Validation;

string baseUrl = "http://localhost/";
void Main()
{
    for(var i = 0; i < 10; i++)
    {
        RunTests();
    }

}

private void RunTests()
{
    var sites = new string[] { 
        "/resource/location",
    };

    RunFor(sites);
}
private void RunFor(string[] sites)
{
   RunTest(sites, 1);
   RunTest(sites, 5);
   RunTest(sites, 25);
   RunTest(sites, 50);
   RunTest(sites, 100);
   RunTest(sites, 500);
   RunTest(sites, 1000);


}
private void RunTest(string[] sites, int iterations, string description = "")
{
    var action = GetAction();

    var watch = new Stopwatch(); 
   // Construct started tasks
   Task<bool>[] tasks = new Task<bool>[sites.Count()];
   watch.Start();

   for(int j = 0; j < iterations; j++)
   {
        for (int i = 0; i < sites.Count(); i++)
        {
            tasks[i] = Task<bool>.Factory.StartNew(action, sites[i]);
        }
   }
   try
   {
       Task.WaitAll(tasks);
   }
   catch (AggregateException e)
   {
       Console.WriteLine("\nThe following exceptions have been thrown by WaitAll()");
       for (int j = 0; j < e.InnerExceptions.Count; j++)
       {
           Console.WriteLine("\n-------------------------------------------------\n{0}", e.InnerExceptions[j].ToString());
       }
   }
   finally
   {
    watch.Stop();
    Console.WriteLine("\"{0}|{1}|{2}\", ",sites.Count(), iterations, watch.Elapsed.TotalSeconds);
   }
}
private Func<object, bool>  GetAction()
{
    baseUrl = baseUrl.Trim('/');
    return (object obj) =>
   {
        var str = (string)obj;
        var client = new RestClient(baseUrl);
        client.Authenticator = new NtlmAuthenticator();
        var request = new RestRequest(str, Method.GET);
        request.AddHeader("Accept", "text/html");
        var response = client.Execute(request);     
        return (response != null);
   };
}   
...