Ответ 1
К сожалению, я знаю только вариант 1 и tbh, который может начать очень тяжело работать.
Но он делает только то, что вы хотите, так быстро, как это происходит.
Удачи.
Недавно я провел некоторое тестирование производительности и анализ приложения ASP.NET с использованием состояния сеанса вне процесса - это необходимо при использовании состояния сеанса в веб-ферме, чтобы можно было восстановить состояние на любом из веб-серверов, например если последующие HTTP-запросы поступают на другой сервер, потому что сеансы не являются "липкими" или исходный сервер не работает и т.д.
Что меня удивило, так это то, что когда я запускал веб-серверы при полной загрузке и профилировал использование ЦП, примерно 99% времени процессора тратили на сериализацию и десериализацию состояния сеанса. Впоследствии мы реализовали настраиваемый государственный сервер "кэширования"; это всегда сериализует состояние, но также сохраняет состояние в памяти, так что, если вы используете липкие сеансы, состояние не нужно десериализовать большую часть времени. Это улучшило пропускную способность сервера в 2 раза; Однако сериализация по-прежнему составляет 98% или более от времени процессора.
Мы получили некоторые дополнительные улучшения в скорости путем "обрезки" ненужных ссылок на объекты между объектами в состоянии сеанса до сериализации - исправление ссылок вручную при десриализации. Это улучшило скорость еще на 10-20% или около того. Причиной здесь является то, что некоторые потери производительности связаны с тем, что встроенная сериализация должна идти по графику указателей объектов, что становится более сложной задачей с большим количеством указателей.
Продолжая исследование, мы писали индивидуальные процедуры сериализации для некоторых наших классов, а не полагались на встроенную сериализацию .Net. Мы обнаружили, что производительность значительно улучшена, примерно в 50x. Похоже, что основная часть загрузки процессора вызвана встроенной сериализацией .Net, которая, в свою очередь, медленна из-за использования использования Reflection для перемещения указателей/графиков объектов и извлечения данных поля.
Очень заманчиво увеличить нашу производительность на 50 раз, таким образом, уменьшая требования к аппаратным средствам веб-сервера с большим коэффициентом (и потребностями в энергии меньшим, но все же значимым фактором). Возможные варианты:
1) Напишите индивидуальную сериализацию. Это проблема из-за сложности задачи и затрат на обслуживание, которые она генерирует, то есть любое изменение состояния класса требует изменения в процедурах сериализации/десериализации.
2) Некоторые решения сторонних разработчиков. Возможно, какой-то продукт, который автоматически генерирует код сохранения состояния/загрузки во время сборки, тем самым устраняя необходимость использования Reflection.
Мне было бы очень интересно узнать, знает ли кто-нибудь о стороннем решении или столкнулся с этой проблемой, поскольку я не нашел упоминания об этом из интернет-поиска.
UPDATE: Некоторые из них предложили своеобразное решение на полпути между встроенной сериализацией по умолчанию и чистыми настраиваемыми процедурами сериализации. Идея заключается в том, что вы реализуете персонализированную сериализацию для классов, которые влияют на производительность больше всего, например. преодолевая ISerializable. Это интересный и многообещающий подход; Тем не менее, я все же думаю, что существует возможность полной замены встроенной сериализации без необходимости писать и поддерживать какой-либо пользовательский код - это невозможно сделать во время выполнения, потому что Reflection необходим для запроса объектов и доступа к личным данным. Но теоретически возможно послепродавать уже построенные сборки и внедрять новые методы в качестве дополнительного шага сборки. Некоторые профилировщики используют этот подход для ввода кода профилирования в сборки после того, как они были созданы компилятором С#. Также я/думаю/где-то читал, что .Net-среда поддерживает инъекции методов в классы - таким образом, все беспорядки с IL потенциально позаботятся.
К сожалению, я знаю только вариант 1 и tbh, который может начать очень тяжело работать.
Но он делает только то, что вы хотите, так быстро, как это происходит.
Удачи.
Еще один вариант заключается в том, чтобы агрессивно отключить ViewState для всех элементов управления, которые не затрагиваются почтовыми сообщениями на стороне сервера.
Вы можете частично настроить сериализацию, выполнив ISerializable
. Если вы сделаете это для худших нарушителей, вы не будете увеличивать обслуживание, но все равно получите некоторое ускорение.
Существует стороннее решение:
Simon Hewitt превосходная библиотека с открытым исходным кодом, см. Оптимизация сериализации в .NET - часть 2.
Я используя его в своем приложении и получил аналогичное ускорение как вы, 20-40 раз.
Это устраняет отражение, которое является причиной замедление, но для списков он поддерживает только несколько родных типов. Так что для Genreric.List ваших собственных типов должно быть явный код где-то или другой. Например. явные петли или что-то умнее, что автоматизирует это. В любом случае это довольно простой и не должен быть помехой для огромного преимущества.
Мы столкнулись с подобными проблемами и разработали несколько способов повышения производительности. Мы используем некоторые из них в нашем картографическом продукте памяти Persistore (в настоящее время бета). В нашем случае мы можем просто получить доступ к сохраненным данным "in situ", потому что он всегда находится в кучке памяти.
Однако один "трюк" заключается в том, чтобы определить ваши данные состояния сеанса (если это возможно) как маршалируемые классы/структуры и "сериализовать", которые используют поддержку .NET marshalling, это может быть очень быстро, но не будет обрабатывать "объект", графики.
Мы также поддерживаем особую постоянство, основанную на двоичной сериализации, но мы также извлекаем и сохраняем метаданные, чтобы управляемый код мог устанавливать/получать поля в памяти, сохраняемой в момент выполнения, без необходимости десериализации всего объекта, это полезно в некоторые настройки (например, ценные бумаги и обновления цен на акции и т.д.). Наша последняя бета-версия поддерживает сериализацию по сети, анонимных типов LINQ, это первый, насколько мне известно.
В любом случае нам было бы интересно иметь новых бета-клиентов, которые подталкивают проблемы ASP.NET и веб-производительности, наша последняя бета-версия очень впечатляет (но не готова до недели nex).
Если кому интересно, просто свяжитесь с нами для получения последней информации о продукте.
Хью Моран
PS: сайт устарел, продукт выходит далеко за рамки того, что описано там.