Комментарии 31
Как вариант — АОП.
0
У динамиков есть четкое применение — интеграция, например с COM.
В вашем же случае проще просто на обычных делегатах сделать что-то вроде того lukencode.com/2010/03/28/c-micro-performance-testing-class/
В вашем же случае проще просто на обычных делегатах сделать что-то вроде того lukencode.com/2010/03/28/c-micro-performance-testing-class/
+1
Да, я в курсе и про интеграцию с COM и про делегаты. В коде я постарался сделать акцент на бизнес-логике и спрятать служебный код. Можно смотреть на это как на «почти АОП».
0
У динамиков «четкое» применение в любом месте, где от этого есть бенефит, а для не какой-то конкретной технологии.
0
У динамиков куча применений. Я периодически использую, как прокси к моделям. Как-то так:
Надо только помнить, что оно не очень-то шустро…
public class DynamicViewModel : DynamicObject, INotifyPropertyChanged
{
/*...*/
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
string propertyName = binder.Name;
PropertyInfo property = _model.GetType().GetProperty(propertyName);
if (property == null || property.CanRead == false)
{
result = null;
return false;
}
result = property.GetValue(_model, null);
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
string propertyName = binder.Name;
PropertyInfo property = _model.GetType().GetProperty(propertyName);
if (property == null || property.CanWrite == false)
return false;
property.SetValue(_model, value, null);
OnPropertyChanged(propertyName);
return true;
}
}
Надо только помнить, что оно не очень-то шустро…
0
Вы, кажется, сделали в точности то, что предлагает фреймворк LinFu в разделе DuckTyping, но тут более конкретно, а там — более общо. Думается, вам будет интересно посмотреть www.codeproject.com/KB/cs/LinFuPart2.aspx (в том числе и на другие статьи этой же серии)
+1
при названии статьи «Измеряем производительность ...» хотелось бы видеть таблички с замерами
а уж если даете ссылки на «похожий подход», то и сравнения подходов
а уж если даете ссылки на «похожий подход», то и сравнения подходов
0
при названии статьи «Измеряем производительность ...» хотелось бы видеть таблички с замерами
Замерами Thread.Sleep(TimeSpan.FromSeconds(rand.Next(5)));? Это действительно интересно?
а уж если даете ссылки на «похожий подход», то и сравнения подходов
Дело в том, что это практически «такой же подход», так что сравнивать можно только названия.
0
Пост на который ссылается автор я писал учень давно, и к тому времени отношение к АОП, по крайней мере, очень сильно изменилось. В частности PostSharp я уже перестал использовать. Конечно, у него есть свои use cases, но практика показывает, что PostSharp не может адекватно (без гигантского кол-ва телодвижений или ручного переписывания IL) влиять на существующие структуры. То есть, он может например обернуть существующий код в
На практике, у меня получается использовать 3 механизма:
А пример кода в статье мне нравится – мне кажется что по сути дела можно попробовать как-то контролировать эту “динамическую подмену” в IoC-контейнере и тем самым профилировать определенные участки кода. (Хотя профиляторы тоже никто не отменял.)
TransactionScope
или например засунуть все вызовы в Task.Factory.StartNew()
, но на практике когда вы начинаете действительно “мешать” аспекты (например, многопооточность+транзакции+stream processing), никакой PostSharp не даст вам возможность декларативно правильно и быстро описать взаимодействие компонент – уровень гранулярности совсем не тот.На практике, у меня получается использовать 3 механизма:
- Для очень простых и ограниченных задач, например когда нужно получить в отсутствии variadic templates набор типов или методов с произвольным количеством аргументов, я использую Т4.
- Для более сложных задач, например когда нужно на основе существующих структур данных наплодить еще данных, я использую транскомпиляцию. Наверное о ней нужен отдельный пост, но суть в том, что я использую механизмы метапрограммирования Boo, компилирую программу, потом декомпилирую ее в C# и вставляю в мои C#-ные проекты. Данный подход реализован отдельным расширением Visual Studio.
- Ну и наконец для безумно сложных задач связанных, например, с многопоточным управлением иерархических конечных автоматов, я использую DSLи.
А пример кода в статье мне нравится – мне кажется что по сути дела можно попробовать как-то контролировать эту “динамическую подмену” в IoC-контейнере и тем самым профилировать определенные участки кода. (Хотя профиляторы тоже никто не отменял.)
0
А пример кода в статье мне нравится – мне кажется что по сути дела можно попробовать как-то контролировать эту “динамическую подмену” в IoC-контейнере и тем самым профилировать определенные участки кода. (Хотя профиляторы тоже никто не отменял.)
Мысль конечно интересная, но думаю, что без прокси, прозрачная «динамическая подмена» вряд ли возможна. Хотя может в каком-нибудь LinFu уже есть решение.
0
Моя вторая статья очень перекликалась с субжем: habrahabr.ru/blogs/net/103558/ — там я тоже сравнивал скорость работы динамиков.
-2
Тут не про скорость работы динамиков, а про использование динамиков в качестве прозрачной прокси для измерения производительности кода.
0
Как бы скорость работы динамиков тоже влияет на результат замера. И очень бы не плохо знать сколько именно добавляет использование динамиков, что я и делал в своей статье.
Я под «перекликались» именно в этом ракурсе имел ввиду.
Я под «перекликались» именно в этом ракурсе имел ввиду.
0
Для таких вещей есть DynamicProxy От Castle'a
Кстати если вызывать методы не через ревлекшн а через экспрешны будет значительно быстрее. DynamicProxy так и делает
Кстати если вызывать методы не через ревлекшн а через экспрешны будет значительно быстрее. DynamicProxy так и делает
0
Для таких вещей есть DynamicProxy От Castle'a
Ещё есть LinFu, PostSharp, Unity.Interception и т.д. Все они попадают под определение «сторонних средств», в топике я написал, что не отказался от их использования целенаправленно.
Кстати если вызывать методы не через ревлекшн а через экспрешны будет значительно быстрее.
Да я знаю, ещё быстрее сформировать делегат через Delegate.CreateDelegate, но, думаю, это не критично для не production кода.
0
У вашего кода есть крупный недостаток: он не type-safe. Для обертки вокруг reflection это оправданно, для обертки вокруг класса с известным во время компиляции публичным интерфейсом — нет.
Такие вещи «традиционно» делаются через динамические прокси.
Такие вещи «традиционно» делаются через динамические прокси.
0
У вашего кода есть крупный недостаток: он не type-safe.
Не вижу в этом крупного недостатка для проверочного кода.
Для обертки вокруг reflection это оправданно, для обертки вокруг класса с известным во время компиляции публичным интерфейсом — нет.
К чему относиться, описанный динамический класс?
Такие вещи «традиционно» делаются через «динамические прокси».
Отвечал уже не раз, но повторюсь:
- В языке нет встроенных средств, чтобы быстро и легко решить эту задачу через динамические прокси;
- «Прибегать к помощи сторонних средств я не хотел», т.к. задача не настолько сложна и магия в runtime мне не нужна;
- Динамические прокси успешно использую в production, цель была не в использование прозрачной замены (например, достаточно попробовать передать wrapper в метод принимающий объект исходного типа, чтобы понять недостаток предложенного подхода).
0
«Не вижу в этом крупного недостатка для проверочного кода.»
Подобного рода «проверочный код» (проверка производительности при реальном использовании объекта; если бы вам не надо было реальное использование, вы бы написали тест) регулярно просачивается в продакшн-код.
Собственно, весь смысл враппера в том, чтобы не знать, что мы вызываем.
«К чему относиться, описанный динамический класс?»
Ко второму, очевидно. Вы же знаете интерфейс класса, который используете.
«В языке нет встроенных средств, чтобы быстро и легко решить эту задачу через динамические прокси;»
Вы свою задачу тоже решаете не встроенными средствами языка, а через Reflection, который встроенное средство платформы.
"«Прибегать к помощи сторонних средств я не хотел», т.к. задача не настолько сложна и магия в runtime мне не нужна;"
При чем тут сторонние средства?
«цель была не в использование прозрачной замены»
А в чем была цель? Если вы хотели получить тестовый код, то он у вас слишком хрупкий.
Подобного рода «проверочный код» (проверка производительности при реальном использовании объекта; если бы вам не надо было реальное использование, вы бы написали тест) регулярно просачивается в продакшн-код.
Собственно, весь смысл враппера в том, чтобы не знать, что мы вызываем.
«К чему относиться, описанный динамический класс?»
Ко второму, очевидно. Вы же знаете интерфейс класса, который используете.
«В языке нет встроенных средств, чтобы быстро и легко решить эту задачу через динамические прокси;»
Вы свою задачу тоже решаете не встроенными средствами языка, а через Reflection, который встроенное средство платформы.
"«Прибегать к помощи сторонних средств я не хотел», т.к. задача не настолько сложна и магия в runtime мне не нужна;"
При чем тут сторонние средства?
«цель была не в использование прозрачной замены»
А в чем была цель? Если вы хотели получить тестовый код, то он у вас слишком хрупкий.
0
Подобного рода «проверочный код» регулярно просачивается в продакшн-код.
В production коде я пользуюсь профайлером.
если бы вам не надо было реальное использование, вы бы написали тест
Я и написал тест для себя, но с удобной мне обёрткой.
Собственно, весь смысл враппера в том, чтобы не знать, что мы вызываем.
Смысл враппера (он же адаптер и обёртка) в том, чтобы адаптировать интерфейс объекта к требованиям системы. А вот смысл прокси как раз служить прозрачной заменой.
Ко второму, очевидно. Вы же знаете интерфейс класса, который используете.
Да, но к динамическому типу данных я могу добавить любые поля, методы и т.д. и узнать об ошибке только в runtime. Даже в Visual Studio я пишу «наугад». Так что, скорее всё-таки первое.
Вы свою задачу тоже решаете не встроенными средствами языка, а через Reflection, который встроенное средство платформы.
Говоря язык, я подразумевал платформу, т.к. в языке нет даже средств вывода и обсуждать его отдельно нет смысла. Уверен вы поняли меня сразу или в платформе есть средства для быстрого и легкого создания «динамических прокси»?
При чем тут сторонние средства?
Думаю из предыдущего вопроса понятно причём.
А в чем была цель? Если вы хотели получить тестовый код, то он у вас слишком хрупкий.
Javascript тоже очень хрупкий, хотя mainstream. Недостаток надёжности (который свойственен любой динамике), компенсируется удобством использования и прозрачностью кода тестов.
0
«Да, но к динамическому типу данных я могу добавить любые поля, методы и т.д. и узнать об ошибке только в runtime. Даже в Visual Studio я пишу «наугад». Так что, скорее всё-таки первое.»
Один из нас не понимает другого. Недостаток вашего кода именно в том, что все ваши ошибки будут в runtime.
«Javascript тоже очень хрупкий, хотя mainstream.»
Он мейнстрим там, где нет менее хрупких средств. И даже там его всячески пытаются сделать менее хрупким, jslint тому свидетельство.
«Недостаток надёжности (который свойственен любой динамике), компенсируется удобством использования и прозрачностью кода тестов. „
С точки зрения кода тестов PerformanceProxy.Create{Of T}(instance) ничем не хуже вашего решения, но при этом еще и дает (должен дать) статическую типизацию. То, что при этом под капотом PerformanceProxy десять MLoC вашего пропьетарного кода или полтора вызова к третьесторонней библиотеке — никого не волнует.
Один из нас не понимает другого. Недостаток вашего кода именно в том, что все ваши ошибки будут в runtime.
«Javascript тоже очень хрупкий, хотя mainstream.»
Он мейнстрим там, где нет менее хрупких средств. И даже там его всячески пытаются сделать менее хрупким, jslint тому свидетельство.
«Недостаток надёжности (который свойственен любой динамике), компенсируется удобством использования и прозрачностью кода тестов. „
С точки зрения кода тестов PerformanceProxy.Create{Of T}(instance) ничем не хуже вашего решения, но при этом еще и дает (должен дать) статическую типизацию. То, что при этом под капотом PerformanceProxy десять MLoC вашего пропьетарного кода или полтора вызова к третьесторонней библиотеке — никого не волнует.
0
Недостаток вашего кода именно в том, что все ваши ошибки будут в runtime.
Да это недостаток, я этого не отрицаю. Я просто хотел донести мысль, что на другой чаше весов «удобством использования и прозрачность кода тестов».
Он мейнстрим там, где нет менее хрупких средств. И даже там его всячески пытаются сделать менее хрупким, jslint тому свидетельство.
Думаю, если бы его хрупкость не была следствием гибкости, то его давно бы заменили. А так вон NodeJS активно развивается, хотя альтернатив уже очень много. JSLint только указывает на потенциальные ошибки, такой статический анализ полезен даже не для хрупкого C# (не зря в VS это отдельный инструмент).
С точки зрения кода тестов PerformanceProxy.Create{Of T}(instance) ничем не хуже вашего решения, но при этом еще и дает (должен дать) статическую типизацию.
Это отличное решение! Более того, оно позволит мне измерить производительность в методах, куда я не могу передать свою динамическую обёртку. Я всего лишь предложил альтернативное, ограниченное решение без использования сторонних средств (или PerformanceProxy где-то в недрах платформы?)
0
«Я просто хотел донести мысль, что на другой чаше весов «удобством использования и прозрачность кода тестов».»
Я уже привел пример того, как сделать не менее удобно и прозрачно (для теста, подчеркиваю).
«Думаю, если бы его хрупкость не была следствием гибкости, то его давно бы заменили.»
Очень сложно заменить технологию, которая уже используется в миллионах мест.
«Я всего лишь предложил альтернативное, ограниченное решение без использования сторонних средств (или PerformanceProxy где-то в недрах платформы?) „
За что вы так не любите сторонние средства?
Я уже привел пример того, как сделать не менее удобно и прозрачно (для теста, подчеркиваю).
«Думаю, если бы его хрупкость не была следствием гибкости, то его давно бы заменили.»
Очень сложно заменить технологию, которая уже используется в миллионах мест.
«Я всего лишь предложил альтернативное, ограниченное решение без использования сторонних средств (или PerformanceProxy где-то в недрах платформы?) „
За что вы так не любите сторонние средства?
0
За что вы так не любите сторонние средства?
За то, что мне нужно их искать, скачивать, разбираться с их API вместо того, чтобы решать бизнес-цели, надеятся на то, что они не криво написаны, модифицировать рабочий код для них (например, вешать атрибуты или помечать члены как virtual)? Я предпочитаю выбирать инструмент под задачу и, если задача требует сторонних средств, я ими воспользуюсь. К счастью, моя задача решилась в рамках платформы.
0
«За то, что мне нужно их искать, скачивать, разбираться с их API вместо того, чтобы решать бизнес-цели, надеятся на то, что они не криво написаны, модифицировать рабочий код для них (например, вешать атрибуты или помечать члены как virtual)? „
Ну так вы выбирайте те средства, проблемы от которых минимальны.
“К счастью, моя задача решилась в рамках платформы. „
Я просто указываю вам на (для меня — фундаментальный) недостаток вашего решения.
(я просто слишком много раз разбирал ошибки, возникающие из-за слабой типизации)
Ну так вы выбирайте те средства, проблемы от которых минимальны.
“К счастью, моя задача решилась в рамках платформы. „
Я просто указываю вам на (для меня — фундаментальный) недостаток вашего решения.
(я просто слишком много раз разбирал ошибки, возникающие из-за слабой типизации)
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Измеряем производительность с помощью DynamicObject