Сколько вычислений стоит за вызовом HttpContext.Current? - PullRequest
5 голосов
/ 14 ноября 2008

Это дорого?

Я разрабатываю HtmlHelper, который визуализируется непосредственно в Response.Output для сохранения ненужного создания строки, и мне нужно выбрать между:

<% Validator.RenderClient(Response.Output); %>

и

<% Validator.RenderClient(); %>

и получите textWriter от HttpContext.Current.Response

Ответы [ 3 ]

3 голосов
/ 08 января 2010

@ Докинз

100 запусков слишком мало, вам нужно выполнить около 10000 раз несколько раз и повторить его, а затем взять среднее значение, чтобы получить надежный результат. Погрешность слишком велика в вашем примере, но это правильный путь.

Вот что я сделал:

var results1 = new List<long>();
var results2 = new List<long>();

for (int j = 0; j < 100; j++)
{
    var sp = new System.Diagnostics.Stopwatch();

    // With HttpContext.Current: 
    sp.Start();
    for (int i = 0; i < 10000; i++)
    {
        HttpContext.Current.Response.Output.Write(i);
    }
    sp.Stop();

    results1.Add(sp.ElapsedTicks);

    // Without: 
    TextWriter output2 = HttpContext.Current.Response.Output;
    sp.Reset();

    sp.Start();
    for (int i = 0; i < 10000; i++)
    {
        output2.Write(i);
    }
    sp.Stop();

    HttpContext.Current.Response.Clear();

    results2.Add(sp.ElapsedTicks);
}

results1.Sort();
results2.Sort();

HttpContext.Current.Response.Write(string.Format("HttpContext.Current={0:0.000}ms, Local variable={1:0.000}ms, R={2:0.0%}<br/>", results1[results1.Count / 2] / (double)TimeSpan.TicksPerMillisecond, results2[results2.Count / 2] / (double)TimeSpan.TicksPerMillisecond, (double)results1[results1.Count / 2] / (double)results2[results2.Count / 2]));

Ваш результат показывает, что разница в производительности составляет 18%, что говорит о том, что он дороже, но на 8% дешевле.

Я перезапустил цифры несколько раз и получил разницу в 10% с погрешностью менее 1%.

Стабилизируется вокруг:

HttpContext.Current=0,536ms, Local variable=0,486ms, R=110,2% 

В любом случае, HttpContext.Current, чтобы создать значительную проблему с производительностью, вам нужно будет назвать ее более 10000 за запрос (стоимость в основном определяется вызовами Response.Write). И это, вероятно, не произойдет.

2 голосов
/ 16 ноября 2008

Это совсем не интенсивно. Я не знаю, почему я не попробовал это в первый раз:

        System.Diagnostics.Stopwatch sp = new System.Diagnostics.Stopwatch();

        // With HttpContext.Current:
        sp.Start();
        for (int i = 0; i < 100; i++)
        {
            HttpContext.Current.Response.Output.Write(i.ToString());
        }
        sp.Stop();
        long result1 = sp.ElapsedTicks;

        // Without:
        TextWriter output2 = HttpContext.Current.Response.Output;
        sp.Reset();
        sp.Start();
        for (int i = 0; i < 100; i++)
        {
            output2.Write(i.ToString());
        }
        sp.Stop();
        long result2 = sp.ElapsedTicks; 

И результаты моего компьютера около:

результат1 = 395 тиков результат2 = 332 тика

Так что это довольно быстро!

2 голосов
/ 14 ноября 2008

от отражателя

public static HttpContext get_Current()
{
    return (ContextBase.Current as HttpContext);
}

вызывает ContextBase который звонит

public static object HostContext
{
    get
    {
        object hostContext = 
          Thread.CurrentThread.GetIllogicalCallContext().HostContext;
        if (hostContext == null)
        {
            hostContext = GetLogicalCallContext().HostContext;
        }
        return hostContext;
    }

...

так что происходит немного «многопоточности»; конкретный, которого я действительно не знаю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...