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

Сделать это с отражением довольно просто:

С Fasterflect это выглядит так:

Мне нравится этот API, он очень интуитивно понятен.

А вот как это выглядит с HyperDescriptor и FastMember:

Теперь давайте проверим это на 1 млн экземпляров MyTypeA и посмотрим, как они это сделают. И Fasterflect, и FastMember работали очень хорошо, хотя HyperDescriptor был в 3 раза медленнее, чем базовое отражение!

Протестируйте 2–1 млн экземпляров MyTypeA и MyTypeB.

Хорошо, но поскольку этот код должен работать со многими типами, мы должны ожидать, что оба

  • типы, обладающие этим свойством, и
  • типы, которые не

Чтобы смоделировать это, давайте введем в тест еще один тип.

Вместо работы с массивом MyTypeA теперь у нас есть смешанный массив как MyTypeA, так и MyTypeB для нашего теста.

и результат для 1M объектов делает интересные чтения:

некоторые наблюдения из этого набора результатов:

  • нам нужно вызывать сеттер только для половины объектов, поэтому отражение происходит быстрее (почти вдвое), чем раньше, что имеет смысл;
  • и FastMember, и HyperDescriptor работают быстрее по той же причине, что и выше;
  • меньшее количество работы оказало гораздо меньшее влияние на FastMember предполагает некоторое кэширование вокруг места вызова (и действительно так оно и есть);
  • Что за хрень с Fasterflect!

Выводы

Мораль этой истории такова: всегда проверяйте утверждения относительно вашего конкретного варианта использования.

Еще один прекрасный пример тому — работа с Джепсеном Кайла Кингсбери. Где он использует подход генеративного тестирования, чтобы проверить, действительно ли базы данных NoSQL обеспечивают модель согласованности, которую они предлагают. Его выводы очень интересно читать, а во многих случаях симпатично тревожно

О, и придерживайтесь FastMember или отражения

Ссылки