2015-07-28 2 views
-1

Я строю систему, где мне придется звонить несколько раз некоторые команды в зависимости от пользовательского ввода, напримерЧто происходит быстрее: проверка нулевого указателя или вызов пустой функции?

void handle(int MouseInput) 
{ 
    switch(MouseInput) 
    { 
    case Move: 
     ActionMove->execute(); 
     // ... 
    case BtnUp: 
     ActionBtnUp->execute(); 
     // ... 
    } 
} 

Но поскольку система параметризуемым, не всегда у меня есть, например, объект actionMove команды (иногда я ничего не делаю в Move).

Что быстрее:

  • Реализация нулевой шаблон объекта, т.е. имеющие объект с execute функции, как так

    execute() {} 
    
  • Или проверки нулевых указателей каждый раз:

    if (ActionBtnUp) ActionBtnUp->execute(); 
    

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

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

+14

[Который быстрее?] (Http://ericlippert.com/2012/12/17/performance-rant/) – CoryKramer

+3

Звучит как преждевременная оптимизация для меня. Пойдите с тем, что сделает ваш код более четким и чистым, и оптимизируйте, если вы найдете здесь проблему производительности. – Luke

+0

Как насчет того, чтобы вы инкапсулировали логику, идите с более простой на данный момент, строите до тех пор, пока у вас не будет большего масштаба, а затем профилируйте оба решения? – KABoissonneault

ответ

4

Для того, чтобы ActionBtnUp быть в состоянии указать на то, что может иметь пустой execute() или может указывать на то, что может действительно сделать что-то полезное, что нужно было бы, чтобы она указывала на базовый класс и сделать execute() виртуальным.

Чтобы компилятор смог оптимизировать этот вызов, он должен был бы статически доказать, какой производный тип указывает указатель. И если он может это сделать, он может, вероятно, сказать, когда указатель имеет значение null и удалить проверку. Поэтому вполне вероятно, что компилятор не будет оптимизировать.

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

5

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

+5

s/несколько тысяч раз/миллион раз/ –

+1

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

+0

@ Планы на орбите в орбите Но просто сравнение? есть еще больше беспокоиться о функциях, которые это вызывает, чем о том, как он решает, что делать. – Snappawapa

0

Имеет ли смысл ваш ActionMove быть пустым? Если да, я считаю, что вам нужно проверить нулевой указатель. Если он не должен быть нулевым, просто используйте ссылку и не проверяйте нулевой указатель.

+2

https://en.wikipedia.org/wiki/Null_Object_pattern (хотя это имеет смысл в языках OO, где все вызовы методов выполняют динамическую отправку) –

3

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

С точки зрения понятности шаблон нулевого объекта может быть лучше - вы проверяете значение null только в одном месте. Тестирование нулевого значения перед каждым разыменованием кажется мне нарушением «Не повторяйте себя».