ASP.NET:HttpModule 性能

发布于 2024-08-12 01:48:17 字数 137 浏览 3 评论 0原文

我已经实现了一个 HttpModule,它拦截每个请求的响应流,并对每个文本/html 类型的响应运行六到十几个 Regex.Replace()。我担心我在这里遭受的性能影响有多大。有什么好方法可以查到吗?我想比较运行和不运行此 HttpModule 的速度。

I've implemented an HttpModule that intercepts the Response stream of every request and runs a half dozen to a dozen Regex.Replace()s on each text/html-typed response. I'm concerned about how much of a performance hit I'm incurring here. What's a good way to find out? I want to compare speed with and without this HttpModule running.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

和我恋爱吧 2024-08-19 01:48:17

我有一些连接到 Response.Filter 流管道来提供资源文件集成、JS/CSS 打包以及将静态文件重写为绝对路径。

只要您在 RegexBuddy 中测试正则表达式的速度超过几百万次迭代,请确保使用 RegexOptions.Compiled,并记住通常最快、最有效的技术是使用正则表达式来广泛识别匹配项,然后使用 C# 来磨练它正是您所需要的。

确保您还依赖于缓存和配置。

我们在这方面取得了很大的成功。

I've a few of these that hook into the Response.Filter stream pipeline to provide resource file integration, JS/CSS packing and rewriting of static files to absolute paths.

As long as you test your regexes in RegexBuddy for speed over a few million iterations, ensure you use RegexOptions.Compiled, and remember that often the quickest and most efficient technique is to use a regex to broadly identify matches and then use C# to hone that to exactly what you need.

Make sure you're also caching and configuration that you rely upon.

We've had a lot of success with this.

拥醉 2024-08-19 01:48:17

Http 模块只是一段常见的代码,因此您可以测量这个特定的正则表达式替换内容的执行时间。这就足够了。将一组典型的响应流作为压力测试的输入,并使用 Stopwatch 类测量替换的执行情况。另请考虑 RegexOptions.Compiled 开关。

Http module is just common piece of code, so you can measure time of execution of this particular regex replace stuff. It is enough. Have a set of typical response streams as input of your stress test and measure executing of the replace using Stopwatch class. Consider also RegexOptions.Compiled switch.

蓝天 2024-08-19 01:48:17

以下是一些想法:

  1. 添加一些 Windows 性能计数器,并使用它们来测量和报告平均计时数据。您还可以仅在时间测量超过特定阈值时增加计数器。将
  2. 跟踪与失败请求跟踪结合使用来收集和报告计时数据。您还可以仅在页面执行时间超过阈值时触发 FRT 报告。
  3. 编写一个单元测试,使用 Windows 操作系统时钟来测量代码执行所需的时间。
  4. 在您的代码中添加一个标志,您可以使用测试页打开或关闭该标志,以启用或禁用您的正则表达式代码,以便轻松进行 A/B 测试。
  5. 使用 WCAT 等负载测试工具来查看启用和不启用代码的情况下每秒可以处理多少页面请求。

Here are a few ideas:

  1. Add some Windows performance counters, and use them to measure and report average timing data. You might also increment a counter only if the time measurement exceeds a certain threshold. and
  2. Use tracing combined with Failed Request Tracing to collect and report timing data. You can also trigger FRT reports only if page execution time exceeds a threshold.
  3. Write a unit test that uses the Windows OS clock to measure how long your code takes to execute.
  4. Add a flag to your code that you can turn on or off with a test page to enable or disable your regex code, to allow easy A/B testing.
  5. Use a load test tool like WCAT to see how many page requests per second you can process with and without the code enabled.
毁虫ゝ 2024-08-19 01:48:17

我最近必须对我编写的 HTTPModule 进行一些 pef 测试,并决定执行一些负载测试来模拟 Web 流量并捕获配置和未配置模块的性能时间。这是我真正了解安装模块的影响的唯一方法。

我通常会使用 Apache Bench 做一些事情(请参阅以下内容了解如何安装,如何在 Windows 7 上安装 apache bench?),但我还必须使用 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);
   };
}   

I recently had to do some pef tests on an HTTPModule that I wrote and decided to perform a couple of load tests to simulate web traffic and capture the performance times with and without the module configured. It was the only way I could figure to really know the affect of having the module installed.

I would usually do something with Apache Bench (see the following for how to intsall, How to install apache bench on windows 7?), but I had to also use windows authentication. As ab only has basic authentication I it wasn't a fit for me. ab is slick and allows for different request scenarios, so that would be the first place to look. One other thought is you can get a lot of visibility by using glimpse as well.

Being that I couldn't use ab I wrote something custom that will allow for concurrent requests and test different url times.

Below is what I came up with to test the module, hope it helps!

// 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);
   };
}   
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文