template
class ExceptionCatcher
{
public:
template
void doit(F&& f)
{
try
{
ExceptionCatcher catcher;
catcher.doit(std::forward(f));
}
catch(const E0 &)
{
std::cout << __PRETTY_FUNCTION__ << '\n';
}
}
};
template
class ExceptionCatcher
{
public:
template
void doit(F&& f)
{
try
{
f();
}
catch(const E0 &)
{
std::cout << __PRETTY_FUNCTION__ << '\n';
}
}
};
Хорошо, поэтому я попытался последовать совету и профилировать свой код, используя указатели и значения. Еще посмотрел ассемблерный код. Похоже, что характеристики производительности на x86 сильно отличаются от PPC. На PPC двоичный интерфейс к C указывал, что аргументы будут помещены в регистры (их было так много на выбор), однако кажется, что даже на 64-битной системе x86 требуется, чтобы аргументы помещались в стек.
Это объясняет, почему на x86 передача по указателю всегда кажется быстрее. Однако я заметил, что компилятор очень хочет встроить. Так что не имело значения, как я это сделал. Итак, я предполагаю, что вывод состоит в том, чтобы использовать любую удобную для вас передачу.
Я думаю, что предпочтения передаются по значению, потому что работа с копиями значений в некоторой степени безопаснее. Мой тестовый пример представлял собой структуру, состоящую из 4 двойников (так что я думаю, что на большинстве платформ это 32 байта).
Если вы поищете в Интернете, вы найдете несколько рекомендаций по размеру байта для передачи по ссылке и значению. Я бы почти никому из этого не поверил. Единственный способ узнать , что конкретная структура является проблемой, - это
Профилировать ее
Это единственный способ на 100% узнать, что существует проблема.
Прежде, чем скептики прыгают. in. Да, есть несколько очевидных случаев. Я бы, например, никогда не передавал структуру по значению, если бы в ней было, скажем, 100 членов. Но это было бы не из-за проблем с производительностью, а больше из-за проблем с пространством стека.
В C ++ есть правило передавать все не из следующего списка как ссылку const
, потому что производительность по существу никогда не будет хуже. Список исключений:
int
и т. Д.), Я не уверен, можно ли это применить непосредственно к C (кроме очевидных типов, которых нет в C), но, возможно, применимы аналогичные рекомендации.
Не пренебрегайте той ролью, которую выравнивание играет в вашем тестировании. Если вы передаете числа с плавающей запятой или удваивается, а ваши структуры не выровнены по соответствующим границам, процессор может получить часть вашего значения, сдвинуть ее, а затем сложить остальное перед сохранением. Я думаю, что большинство современных компиляторов будут использовать DTRT (выравнивая структуру, когда она объявлена), но если вы оптимизируете пространство, то это, вероятно, будет проблемой.
Хммм, теперь, когда я думаю об этом, отнеситесь к этому серьезно. скверны, так как я не занимался низкоуровневым кодированием на архитектуре x86 со времен Pentium Pro ...
Обычно примитивные типы я передаю по значению, все остальное по ссылке. Это мое практическое правило.
Некоторые компиляторы могут определить оптимальный размер за вас. Если я правильно помню, компилятор TI28xx автоматически преобразует передачу по значению в передачу по ссылке, если структура превышает определенный размер.