dotSITE
Вопросы/Ответы Учебник по ASP.NET Форумы
новости материалы решения форумы группы настройки/о проекте
Логин/Регистрация
Логин:
Пароль:
Запомнить вас:
Регистрация
Забыли пароль?

Комментарии

Методы повышения производительности .NET приложений

Цикл статей

Методы повышения производительности .NET приложений

Этот раздел адресован разработчикам, желающим достигнуть оптимальной производительности приложений в управляемом мире. Приведены образцы кода, описания и рекомендации разработки для баз данных, Windows Forms и ASP приложений.

 

Обзор

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

 

Этот раздел состоит из нескольких частей, в которых подсказки организованы в соответствии с типами проектов и категориями разработчиков. Первый набор подсказок относится к любому языку программирования и содержит совет, который поможет вам в любом языке программирования Общеязыковой среды выполнения (CLR). Далее следуют подсказки для ASP.NET.

 

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

Рекомендации по повышению производительности для всех приложений

Здесь приведено несколько подсказок, которые следует учитывать при работе с любым языком программирования в CLR. Они подходят для любого из них и должны быть первоочередными средствами борьбы с проблемами производительности.

Формируйте меньшее количество исключительных ситуаций

Формирование исключительной ситуации может требовать очень больших затрат производительности, так что убедитесь, что вы не формируете их слишком много. Чтобы увидеть, сколько исключительных ситуаций формирует ваше приложение, используйте Perfmon. Вы будете удивлены обнаружив, что определенные области вашего приложения формирует больше исключительных ситуаций, чем вы ожидали. Для большей конкретизации вы также можете проверить их количество программно, применяя Performance Counters (Счетчики производительности).

 

Обнаружение и удаление кода, формирующего большое количество исключительных ситуаций, может привести к большому выигрышу в производительности. Помните, что не надо ничего делать с блоками try/catch: вы несете потери только при формировании фактической исключительной ситуации. Вы можете использовать столько блоков try/catch, сколько хотите. Использование исключительных ситуаций неоправданно там, где вы теряете производительность. Например, вы должны избегать использования исключительных ситуаций для формирования управляющей логики.

 

Вот простой пример того, как дороги могут быть исключительные ситуации: мы просто попытаемся прогнать цикл For, генерируя тысячи исключительных ситуаций и обрабатывая их. Попытайтесь закомментировать оператор throw и вы увидите разницу в скорости: эти исключительные ситуации приводят к гигантским непроизводительным издержкам.

 

public static void Main(string[] args){

  int j = 0;

  for(int i = 0; i < 10000; i++){

    try{  

      j = i;

      throw new System.Exception();

    } catch {}

  }

  System.Console.Write(j);

  return;  

}

  • Будьте внимательны! Среда выполнения может самостоятельно формировать исключительные ситуации! Например, Response.Redirect() формирует исключительную ситуацию ThreadAbort. Даже если вы явно не формируете исключительную ситуацию, вы, возможно, используете функции, которые делают это. Используйте Perfmon, чтобы получить представление о реальной ситуации, и отладчик, чтобы найти источник.

 

  • Для разработчиков Visual Basic: Visual Basic включает проверку int по умолчанию, чтобы гарантировать формирование исключительных ситуаций в случае возникновения таких ситуаций, как переполнение и деление на нуль. Возможно, вы захотите отключить эту возможность, чтобы выиграть в производительности.

 

  • Используя СОМ, вы должны помнить, что HRESULTS могут возвратиться как исключительные ситуации. Убедитесь, что вы внимательно отслеживаете это.

Делайте емкие вызовы

Емкий вызов – это вызов функции, который выполняет несколько задач, так же как метод, инициализирующий несколько полей объекта. Его надо рассматривать в противопоставлении неёмкому вызову, который выполняет очень простые задачи и использует для этого множество вызовов (например, установка каждого поля объекта отдельным вызовом). В методах, в которых непроизводительные расходы выше, чем для простых вызовов методов внутри AppDomain, важно делать емкие вызовы. Вызовы P/Invoke, interop и remoting приводят к непроизводительным расходам и вы хотите пореже их использовать. В каждом из этих случаев надо попытаться спроектировать приложение так, чтобы оно не использовало маленькие, частые вызовы, которые приводят к таким большим непроизводительным расходам.

 

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

 

  • Осуществить маршаллинг данных
  • Настроить соглашение о вызовах
  • Защитить регистры, сохраняемые вызываемым объектом
  • Переключить режим потока таким образом, чтобы GC не блокировал неуправляемые потоки
  • Установить оболочку, обрабатывающую исключительные ситуации, на вызовы в управляемом коде
  • Заняться управлением потоков (необязательно)

 

Чтобы уменьшить время перехода через границы, старайтесь по возможности пользоваться P/Invoke. Непроизводительные расходы соответствуют 31 команде плюс затраты на маршаллинг, если нужен маршаллинг данных, и только 8 в противоположном случае. Взаимодействие СОМ намного более дорого, более 65 команд.

 

Маршаллинг данных не всегда требует больших затрат. Примитивным типам вообще не нужен маршаллинг, также дешевы  классы с четкой компоновкой. Реальное снижение производительности происходит во время преобразования данных, например, конвертации текста из ASCI в Unicode. Убедитесь, что данные, передаваемые через границы управляемого кода преобразуются только в том случае, если это необходимо: может оказаться, что просто соглашаясь на определенный тип данных или формат в вашей программе, вы можете избежать больших затрат на маршаллинг.

 

Следующие типы называют блитируемыми, имея ввиду, что их можно копировать прямо через управляемую/неуправляемую границу вообще без маршаллинга: sbyte, byte, short, ushort, int, uint, long, ulong, float и double. Вы можете свободно передавать эти типы без всяких потерь производительности, так же как типы значений и одномерные массивы, содержащие блитируемые типы. Мельчайшие детали маршаллинга можно изучить дополнительно в библиотеке MSDN.

Разработка с использованием типов значений

По возможности используйте простые структуры, даже когда редко упаковываете и распаковываете. Вот простой пример, демонстрирующий разницу в скоростях:

 

using System;

namespace ConsoleApplication{

  public struct foo{

    public foo(double arg){ this.y = arg; }

    public double y;

  }

  public class bar{

    public bar(double arg){ this.y = arg; }

    public double y;

  }

  class Class1{

    static void Main(string[] args){

      System.Console.WriteLine("starting struct loop...");

      for(int i = 0; i < 50000000; i++)

      {foo test = new foo(3.14);}

      System.Console.WriteLine("struct loop complete.

                                starting object loop...");

      for(int i = 0; i < 50000000; i++)

      {bar test2 = new bar(3.14); }

      System.Console.WriteLine("All done");

    }

  }

}

 

Когда запустите этот пример, вы увидите, что цикл с использованием структуры выполняется на порядок быстрее. Однако важно быть осторожным при использовании типов значений в качестве объектов. Это создает дополнительные затраты на упаковку и распаковку, которые могут в конце концов превысить затраты, которые могли бы возникнуть, если бы вы использовали объекты! Чтобы увидеть это на деле, измените код и используйте массив структур foo и объектов bar. Вы обнаружите, что производительность приблизительно та же.

 

Примечание: Типы значений гораздо менее гибкие, чем объекты, и при некорректном использовании очень сильно снижают производительность. Необходима крайняя осторожность в том, когда и как их использовать.

 

Поработайте с примером, приведенном выше, сохраняя foos и bars в массивах или хэш-таблицах. Вы увидите, что выигрыш в скорости пропадет сразу же, как только появится хотя бы одна операция упаковывания и распаковывания.

 

Можно проследить за тем, как интенсивно вы используете упаковку и распаковку, просмотрев распределения и сборки мусора GC. Это можно сделать прямо с помощью Perfmon или через Performance Counters в коде.

 

Полную информацию по типам значений смотрите в Приложении Б.

Используйте AddRange для добавления групп элементов

Вместо многократного добавления каждого элемента коллекции по отдельности, используйте AddRange, чтобы добавить сразу всю коллекцию. Практически все элементы управления Windows и коллекции имеют и метод Add, и метод AddRange, и каждый из них оптимизирован для разных целей. Add используется для добавления отдельного элемента, в то время как использование AddRange приводит к некоторым потерям производительности, но выигрывает при добавлении множества элементов. Здесь приведены только некоторые из классов, поддерживающих Add и AddRange:

 

  • StringCollection, TraceCollection и т.д.
  • HttpWebRequest
  • UserControl
  • ColumnHeader

Ограничьте ваш Working Set

Чтобы поддерживать небольшие размеры Working Set, минимизируйте число используемых сборок. Если вы загружаете всю сборку просто для того, чтобы использовать один метод, вы платите огромную цену за очень несущественные преимущества. Посмотрите нельзя ли скопировать функциональные возможности этого метода, используя код, который вы уже загрузили.

 

Отслеживание размера Working Set является довольно сложной задачей и может стать темой целой статьи. Здесь приведены некоторые подсказки, которые помогут вам:

 

  • Чтобы отслеживать Working Set используйте vadump.exe.

 

  • Просмотрите Perfmon или Performance Counters. Они могут предоставить вам детальную информацию о количестве загруженных классов или количестве методов, которые подвергались JIT компиляции. Вы можете узнать, сколько времени потрачено на загрузку или какой процент времени выполнения потрачен на подкачку файлов.

Используйте циклы For для перебора символов в строке

В C# ключевое слово foreach позволяет пройти по элементам списка, строки и т.д. и осуществить операции над каждым из них. Это очень мощный инструмент, т.к. он работает как универсальный нумератор для многих типов. Альтернативой этого обобщения является скорость, и если вы действительно часто используете итерацию строк, лучше используйте цикл For. Поскольку строки – это простые массивы символов, их можно пройти с намного меньшими потерями, чем другие структуры. JIT компиляция достаточно интеллектуальна (в большинстве случаев), чтобы оптимизировать граничные проверки и другие вещи внутри цикла For, но при обходах foreach этого сделать нельзя. В результате цикл For для строк работает более, чем в пять раз быстрее, чем цикл foreach.

 

Здесь приведен простой тестовый метод для демонстрации разницы скоростей. Попытайтесь запустить его, затем удалите цикл For и раскомментируйте выражение foreach.

 

public static void Main(string[] args) {

  string s = "monkeys!";

  int dummy = 0;

 

  System.Text.StringBuilder sb = new System.Text.StringBuilder(s);

  for(int i = 0; i < 1000000; i++)

    sb.Append(s);

  s = sb.ToString();

  //foreach (char c in s) dummy++;

  for (int i = 0; i < 1000000; i++)

    dummy++;

  return;  

  }

}

 

Примечание: Foreach намного более удобочитаемый и в будущем он станет более быстрым, чем цикл For, для таких специальных случаев, как строки.

Используйте StringBuilder для работы со строками

После изменения строки среда выполнения создаст новую строку и вернет ее, а оригинальная строка будет собрана сборщиком мусора. В большинстве случаев это быстрый и простой процесс, но частые изменения строки приводят к снижению производительности: все эти размещения в конечном концов приводят к непроизводительным расходам. Здесь приведены два примера. Первый - это простая программа, в которой происходит дополнение строки 50 000 раз; во втором примере для модификации строки используется объект StringBuilder. Код, использующий StringBuilder, выполняется намного быстрее, если вы запустите оба этих примера, это сразу станет очевидным.

 

namespace ConsoleApplication1.Feedback{

  using System;

 

  public class Feedback{

    public Feedback(){

      text = "You have ordered: \n";

    }

 

    public string text;

 

    public static int Main(string[] args) {

      Feedback test = new Feedback();

      String str = test.text;

      for(int i=0;i<50000;i++){

        str = str + "blue_toothbrush";

      }

      System.Console.Out.WriteLine("done");

      return 0;

    }

  }

}

 

namespace ConsoleApplication1.Feedback{

  using System;

 

  public class Feedback{

    public Feedback(){

      text = "You have ordered: \n";

    }

 

    public string text;

 

    public static int Main(string[] args) {

      Feedback test = new Feedback();

      System.Text.StringBuilder SB =

        new System.Text.StringBuilder(test.text);

      for(int i=0;i<50000;i++){

        SB.Append("blue_toothbrush");

      }

      System.Console.Out.WriteLine("done");

      return 0;

    }

  }

}

 

Посмотрите в Perfmon сколько времени экономится, когда не надо распределять тысячи строк. Посмотрите на счетчик "% времени в GC" под списком .NET CLR Memory. Здесь вы также можете увидеть число сохраненных распределений, а так же статистику сборки мусора.

 

Примечание: с созданием объекта StringBuilder связаны некоторые непроизводительные затраты времени и памяти. На машинах с быстрой памятью имеет смысл применять StringBuilder, если вы делаете около пяти операций. Как правило, 10 и более строковых операций являются оправданием для непроизводительных расходов на любой машине, даже самой медленной.

Прекомпилируйте приложения Windows Forms

Методы подвергаются JIT компилированию при первом использовании. Это означает, что, чем больше методов вызывает ваше приложение при запуске, тем дольше будет идти загрузка программы. Windows Forms используют большое количество совместно используемых библиотек в ОС, и непроизводительные расходы при их запуске могут быть намного большими, чем для любых других приложений. Хотя это и не всегда так, но прекомпилирование приложений Windows Forms обычно приводит к выигрышу в производительности.

 

Microsoft обеспечивает возможность прекомпилировать приложения, вызывая ngen.exe. Вы можете запустить ngen.exe во время инсталляции или перед поставкой приложения. Определенно больший смысл имеет запускать ngen.exe во время инсталляции, т.к. в этом случае вы сможете удостовериться, что приложение оптимизировано для машины, на которой оно было инсталлировано. Если вы запускаете ngen.exe до поставки программы, вы ограничиваете оптимизацию тем, что доступно на вашей машине. В таблице приведены объективные времена запуска для ShowFormComplex, приложений winforms с примерно сотней элементов управления.

 

Состояние кода

Время

Framework JITed

 

ShowFormComplex JITed

 

3.4 c

Framework Precompiled, ShowFormComplex JITed

2.5 c

Framework Precompiled, ShowFormComplex Precompiled

2.1c

 

Каждый эксперимент проводился после перезагрузки. Как вы видите, приложения Windows Forms сразу используют много методов, поэтому прекомпилирование приводит к существенным выигрышам в производительности.

Используйте Jagged массивы

JIT компиляция оптимизирует jagged массивы ('массивы массивов') более эффективно, чем прямоугольные массивы, и разница весьма заметна. Данная таблица демонстрирует выигрыш в производительности при использовании jagged массивов вместо прямоугольных массивов в C# и Visual Basic (большие числа лучше):

 

 

C#

Visual Basic 7

Assignment (jagged)

 

Assignment (rectangular)

14.16

 

8.37

12.24

 

8.62

Neural Net (jagged)

 

Neural net (rectangular)

4.48

 

3.00

4.58

 

3.13

Numeric Sort (jagged)

 

Numeric Sort (rectangular)

4.88

 

2.05

5.07

 

2.06

 

Как видите, применение jagged массивов может привести к поразительному повышению производительности.

Поддерживайте размер буфера ввода/вывода (IO) в пределах 4KB - 8KB

Практически для всех приложений размер буфера в пределах 4KB - 8KB обеспечит максимальную производительность. В особых случаях вы, возможно, сможете достичь лучших результатов с большим буфером (загрузка больших графических объектов предсказуемого размера, например), но в 99.99% случаев это только приведет к ненужной растрате памяти. Во всех буферах, унаследованных от BufferedStream, предоставлена возможность установить любой желаемый размер, но в большинстве случаев 4 и 8 обеспечат наилучшую производительность.

Будьте внимательны с асинхронным вводом/выводом (IO)

В редких случаях вы сможете получить выгоду от асинхронного ввода/вывода (IO). Одним из примеров может быть загрузка и декомпрессия ряда файлов: вы можете считать биты из одного потока, декодировать их и записать в другой поток. Чтобы эффективно использовать асинхронный ввод/вывод, необходимы большие усилия, и если что-то сделано неправильно, это приведет только к потерям производительности. Преимущество асинхронного ввода/вывода в том, что при правильном его использовании есть возможность достичь в десять раз большей производительности.

Рекомендации по доступу к базам данных

Основной идеей при совершенствовании доступа к базам данных является использование только тех функциональных возможностей, которые необходимы для этого, и разработка с использованием 'разъединенного' подхода: вместо поддержания открытым длительное время одного соединения делать несколько соединений последовательно. Вы должны разрабатывать приложения с учетом этих изменений.

 

Microsoft для обеспечения максимальной производительности рекомендует стратегию N-связей, как альтернативу прямому соединению клиент-база данных. Учитывайте эти при разработке приложений, т.к. многие технологии оптимизируются, чтобы использовать преимущества множества связей.

Используйте оптимальный управляемый провайдер

Вместо того, чтобы полагаться на универсальный провайдер, сделайте правильный выбор управляемого провайдера. Есть управляемые провайдеры, написанные специально для различных баз данных, например, SQL (System.Data.SqlClient). При использовании универсального интерфейса, например, System.Data.Odbc, в то время как есть возможность использования специализированного компонента, вы потеряете в производительности занимаясь дополнительными уровнями преобразований. Использование оптимального провайдера даст возможность использовать различные языки: Управляемый  SQL клиент обращается к SQL базе данных на TDS, что намного лучше, чем универсальный OleDbprotocol.

Используйте Data Reader вместо Data Set когда это возможно

Используйте data reader как можно чаще. Это обеспечивает быстрое считывание данных, которые могут быть кэшированы по желанию пользователя. Data reader – это просто поток, который обеспечивает возможность считывать данные по мере их поступления и затем удаляет их без сохранения в dataset для дальнейшей навигации. Потоковый подход более быстрый и вызывает меньшие непроизводительные затраты, поскольку вы можете сразу использовать данные. Чтобы решить, имеет ли смысл кэширование для навигации, вы должны определить, как часто вам нужны одни и те же данные. Данная таблица приведена, чтобы продемонстрировать разницу между DataReader и DataSet в ODBC и SQL провайдерах при извлечении данных с сервера (большие числа лучше):

 

 

ADO

SQL

DataSet

801

2507

DataReader

1083

4585

 

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

Используйте Mscorsvr.dll для многопроцессорных машин

Для автономных серверных приложений и приложений среднего уровня (middle-tier) убедитесь, что используете mscorsvr для многопроцессорных машин. Mscorwks не оптимизированы по масштабированию и пропускной способности, а серверные версии имеют несколько оптимизаций, которые обеспечивают им хорошую масштабируемость, когда доступно более одного процессора.

По возможности используйте хранимые процедуры

Хранимые процедуры являются высоко оптимизированными инструментальными средствами, которые при эффективном использовании обеспечивают великолепную производительность. Используйте хранимые процедуры для обработки вставок, обновлений и удалений с data adapter. Хранящиеся процедуры не надо интерпретировать, компилировать или даже передавать от клиента, что уменьшает непроизводительные расходы как сетевого трафика, так и сервера. Убедитесь, что используете CommandType.StoredProcedure вместоCommandType.Text.

Будьте осторожны с использованием строк динамического соединения

Организация связного пула – лучший способ повторного использования соединений для множества запросов, чем затраты на открытие и закрытие соединения для каждого отдельного запроса. Это делается неявно, но вы получаете один пул на отдельную строку соединения. Если вы генерируете строки соединения динамически, убедитесь, что каждый раз строки идентичны, чтобы произошла организация связного пула. Также помните, что если происходит делегирование, вы получаете один пул на клиента. Вы можете установить много опций для связного пула и используя Perfmon можете отслеживать время ответа, количество транзакций в секунду и т.д.

Отключите возможности, которые не используете

Отключите автоматическое управление пранзакциями, если не используете его. Для SQL управляемого провайдера это делается посредством строки соединения:

 

SqlConnection conn = new SqlConnection(

"Server=mysrv01;

= Integrated Security true;

Enlist=false");

 

При заполнении набора данных с помощью адаптера данных не получайте информацию первичного ключа, если вам не надо этого делать (т.е. не задавайте MissingSchemaAction.AddWithKey):

 

public DataSet SelectSqlSrvRows(DataSet dataset,string connection,string query){

    SqlConnection conn = new SqlConnection(connection);

    SqlDataAdapter adapter = new SqlDataAdapter();

    adapter.SelectCommand = new SqlCommand(query, conn);

    adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;

    adapter.Fill(dataset);

    return dataset;

}

 

Избегайте команд, генерируемых автоматически

При использовании адаптера данных избегайте команд, генерируемых автоматически. Они требуют дополнительных обращений к серверу для извлечения метаданных и понижают уровень контроля взаимодействия. Хотя команды, генерируемые автоматически, использовать удобно, в требовательных к производительности приложениях стоит делать это самостоятельно.

Правильно используйте ADO

Помните, что при выполнении команды или вызов функции заполнения адаптера, каждая запись, определенная вашим запросом, возвращается.

 

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

 

Если надо, реализовывайте пейджинг  без установления соединения. Вы можете добавить дополнительные записи в набор данных:

 

  • убедившись, что первичный ключ присутствует в таблице
  • изменяя команду select адаптера данных по обстановке, и
  • вызывая Fill

Поддерживайте небольшие размеры своих наборов данных

В наборы данных помещайте только необходимые вам записи. Помните, что набор данных все свои данные сохраняет в памяти, и чем больше данных вы запрашиваете, тем больше времени понадобится для их передачи.

Как можно чаще используйте последовательный доступ

Используйте CommandBehavior.SequentialAccess с data reader. Это важно при работе с blob типами данных, т.к. дает возможность считывать данные маленькими порциями. Поскольку вы можете в данный момент времени работать только с одной частью данных, исчезает задержка на загрузку большого количества данных. Если нет необходимости работать сразу со всем объектом, использование последовательного доступа обеспечит намного лучшую производительность.

Рекомендации по повышению производительности для ASP.NET приложений

Активно используйте кэширование

При разработке приложений, используя ASP.NET, будьте внимательны с кэшированием. В серверных версиях ОС у вас есть множество средств для тонкой настройки использования кэшей со стороны сервера и клиента. В ASP.NET для повышения производительности есть несколько возможностей и инструментальных средств.

 

Выходное кэширование – сохраняет статический результат ASP.NET запроса. Определяется с помощью директивы <@% OutputCache %>:

 

  • Duration — время существования элемента в кэше
  • VaryByParam — различие содержимого кэша по Get/Post параметрам
  • VaryByHeader — различие содержимого кэша по Http заголовкам
  • VaryByCustom — различие содержимого кэша по типу браузера
  • Переопределите, чтобы различать по тому параметру, какому хотите:

 

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

 

a)      VaryByControl проверяет кэшированные элементы по значениям элемента управления

 

·         Cache APIобеспечивает очень хорошую детализацию для кэширования, сохраняя хэш-таблицу  кэшированных объектов в памяти (System.web.UI.caching). Также:

 

a)      Включает зависимости (ключ, файл, время)

b)      Автоматически уничтожает неиспользуемые элементы

c)      Поддерживает обратные вызовы

 

Разумное использование кэширования может обеспечить превосходную производительность. Важно продумать то, какой тип кэширования вам необходим. Представьте сложный коммерческий сайт с несколькими статическими страницами для регистрации, а затем множество динамически генерируемых страниц, содержащих графические элементы и текст. Вы, возможно, захотите использовать кэширование для этих страниц регистрации и фрагментарное кэширование для динамических страниц. Панель инструментов, например, может кэшироваться фрагментарно. Для еще лучшей производительности вы можете кэшировать часто используемые графические элементы и шаблонные тексты, часто появляющиеся на сайте, используя Cache API.

Используйте Session State только по необходимости

Одной чрезвычайно мощной особенностью ASP.NET является возможность сохранения session state для пользователей, например, корзину покупок на сайте электронной коммерции или историю браузера. Т.к. это свойство используется по умолчанию, даже если вы не пользуетесь им, расходуется память. Если вы не используете session state, выключите его и предохраните себя от непроизводительных расходов добавлением <@% EnabledSessionState = false %> в свое приложение.

 

Для страниц, только считывающих session state, можно выбрать EnabledSessionState=readonly. В этом случае затраты будут меньшими, чем на полное считывание/запись состояния соединения, и этот вариант более приемлем, если необходима только часть функциональных возможностей.

Используйте View State только по необходимости

Примером View State может быть длинная форма, которую пользователи должны заполнить: если они нажимают кнопку Back в своем браузере и затем возвращаются, форма останется заполненной. Когда данные функциональные возможности не используются, это состояние расходует память и производительность. Возможно, наибольшая потеря производительности в этом случае происходит из-за того, что возвращаемые данные должны посылаться по сети каждый раз при загрузке страницы, чтобы обновить и проверить кэш. Т.к. это происходит по умолчанию, необходимо обозначить, что вы не хотите использовать View State, следующим образом: <@% EnabledViewState = false %>.

Избегайте STA COM

Апартаменты СОМ созданы для работы с потоковой и неуправляемой средой. Существует два вида апартаментов СОМ: однопоточный и многопоточный. Многопоточный (MTA) СОМ разработан для обработки многопоточности, в то время как однопоточный (STA) СОМ основывается на системе обмена сообщениями, чтобы сериализовывать запросы потока. Управляемый мир потоконезависим, и использование STA COM требует, чтобы все неуправляемые потоки совместно использовали один поток для взаимодействия. В результате - огромное снижение производительности, т.е. этого надо избегать. Если вы не можете перенести апартамент COM объект в управляемый мир, используйте <@%AspCompat = "true" %> для страниц, которые его используют.

Удалите ненужные Http модули

В зависимости от используемых возможностей удалите неиспользуемые или ненужные http модули из конвейера (pipeline).

Избегайте использования свойства Autoeventwireup

Вместо того, чтобы полагаться на autoeventwireup, переопределите события Page. Например, вместо записи метода Page_Load() попытайтесь перезагрузить public метод void OnLoad(). Это освобождает среду выполнения от необходимости выполнять CreateDelegate() для каждой страницы.

Кодируйте, используя ASCII, когда нет необходимости использовать UTF

По умолчанию, ASP.NET  настроена так, чтобы кодировать запросы и ответы, как UTF-8. Если ASCII – это все, в чем нуждается ваше приложение, устранение затрат на UTF может повысить производительность. Обратите внимание, что это можно делать только для каждого отдельного приложения.

Используйте оптимальную процедуру аутентификации

Существует несколько способов аутентификации пользователя и несколько более дорогих, чем другие (в порядке возрастания затрат: None, Windows, Forms, Passport). Убедитесь, что используете самую дешевую из подходящих для вашего случая.

как классы.


Контакт Реклама на сайте Спонсорам Веб мастерам

Лицензионное соглашение - © 2000-2010 dotSITE
Хостинг .NET предоставлен PARKING.RU
Поддержку сайта осуществляет Murano Software Inc., Offshore software development