Не -виртуальный интерфейс? (Нужна очень производительная низкоуровневая абстракция)

Я пытаюсь микро -оптимизировать свой код на очень низком уровне архитектуры приложения. Итак, вот мой конкретный сценарий:

  • У меня есть класс синтаксического анализатора , который анализирует узлы графового файла (, ребра, записи смежности и т. д.)
  • Формат файла версионный, поэтому для каждой версии существуют парсеры, реализованные как отдельные классы(ParserV1, ParserV2,... ).
  • Парсеры предоставляют те же функции для некоторых верхних уровней приложения. Таким образом, они реализуют один и тот же «интерфейс ».
  • В C++ я бы реализовал такой интерфейс как абстрактный класс, в котором все функции были бы чистыми виртуальными .
  • Поскольку виртуальные функции нуждаются в другом поиске в памяти и не могут быть связаны статически во время компиляции, и --что гораздо важнее --, они не позволят встраивать небольшие методы в классы синтаксического анализатора, используя классический под-классовая идиома не приведет к наилучшей производительности, которую я могу достичь.

[Прежде чем описывать мои возможные решения, я хочу объяснить, почему я делаю микро -оптимизацию здесь (вы можете пропустить этот абзац ):Класс парсера имеет множество мелких методов, где "маленький" означает, что они мало что делают. Большинство из них считывают только один или два байта или даже только один бит из кэшированного битового потока. Таким образом, должна быть возможность реализовать их очень и очень эффективным способом, когда встроенный вызов функции требует лишь нескольких машинных команд. Методы вызываются очень часто в приложении, так как они ищут атрибуты узлов в очень большом графе (всемирной -широкой дорожной сети ),что может произойти около миллиона раз за запрос пользователя, и такой запрос должен быть максимально быстрым.]

Какой путь сюда пройти? Я вижу следующие способы решения проблемы:

  1. Напишите интерфейс с чисто виртуальными методами и создайте его подкласс. Спектакль пострадает.
  2. Не пишите такой интерфейс. Каждый парсер определяет одни и те же методы самостоятельно. На верхнем уровне (, который использует синтаксический анализатор ), имеются указатели (в качестве членов )на каждый подкласс версии. В начале создайте конкретный анализатор, который следует использовать. Используйте блок switch и приведите экземпляр парсера к явному подклассу при каждом доступе к функции. Будет ли производительность лучше? (блок if/switch против поиска в виртуальной таблице ).
  3. Смешайте два решения 1. + 2. :Напишите интерфейс с чисто виртуальными методами для редко используемых методов, где производительность не очень критична. Если это критично, не предоставляйте виртуальный метод, а используйте второй метод.
  4. Улучшение 2. :Обеспечить не -виртуальные методы в абстрактном классе; сохранить номер версии в качестве переменной-члена в абстрактном классе (в виде собственной информации о типе времени выполнения )и реализовать блоки и приведения if/switch в этих методах; затем вызовите методы в подклассе. Это обеспечивает как встраивание, так и статическую привязку.

Есть ли лучшие способы решить эту проблему? Есть ли какая-нибудь идиома для этого?

Чтобы уточнить, у меня есть много функций, которые не зависят от версии -(, по крайней мере, до сих пор ), и, таким образом, идеально вписываются в какой-то суперкласс. Я буду использовать стандартную схему классификации sub -для большинства функций, в то время как этот вопрос охватывает только решение для зависимых от версии -функций, которые необходимо оптимизировать. (Некоторые из них вызываются не очень часто, и я, конечно, могу использовать виртуальные методы в таких случаях. )Помимо этого,Мне не нравится идея заставлять класс синтаксического анализатора решать, какие методы должны быть производительными, а какие нет. (Хотя можно было бы и так.)

7
задан leemes 2 July 2012 в 22:54
поделиться