我实现了一个HttpModule,拦截每个请求的响应流,并对每个text/html类型的响应运行六到十二个Regex.Replace()操作。我担心这会造成多大的性能损失。有什么好方法可以找出来吗?我想比较一下使用和不使用这个HttpModule时的速度。
我实现了一个HttpModule,拦截每个请求的响应流,并对每个text/html类型的响应运行六到十二个Regex.Replace()操作。我担心这会造成多大的性能损失。有什么好方法可以找出来吗?我想比较一下使用和不使用这个HttpModule时的速度。
Http模块只是一段常见的代码,因此您可以测量执行此特定正则表达式替换操作的时间。这已经足够了。将一组典型的响应流作为压力测试的输入,并使用Stopwatch
类来测量替换的执行时间。还要考虑RegexOptions.Compiled
开关。
以下是一些想法:
最近我需要对我编写的HTTPModule进行一些性能测试,决定执行一些负载测试来模拟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);
};
}