В чем разница в производительности между различными методами инициализации класса или структуры? - PullRequest
0 голосов
/ 08 октября 2018

У нас есть разные типы инициализации переменной класса или члена структуры в c ++, один из них:

struct foo {
    foo() : a(true), b(true), c(true) {}
    bool a;
    bool b;
    bool c;
 } bar;

, а другой:

struct foo {
    bool a = true;
    bool b = true;
    bool c = true;
 } bar;

Есть ли различия между ними?

какой из них лучше использовать?

1 Ответ

0 голосов
/ 09 октября 2018

TL; DR Не заботьтесь о таких мелочах, если вы не знаете, что должны.И если вам нужно, вам нужно проанализировать конкретную сборку.

В общем, с чисто языковой точки зрения такие вопросы не имеют смысла.Для чего это стоит, компилятор c ++ может нанести вред производительности, если он этого пожелает.Любая программа, демонстрирующая такое же поведение, также легальна, и производительность не является видимым эффектом.

Разговор о производительности имеет смысл только в конкретном приложении, которое представляет собой конкретную сборку с использованием определенного компилятора и конфигурации, особенно оптимизации.

Полное изучение: Я буду использовать clag 7.0.0 на проводнике компилятора Godbolt

Ваш случай странный, поскольку он определяет глобальные значения. Для оптимизации по умолчаниюпараметры:

  1. c'tor был сгенерирован и объект сохранен как нули
  2. не было кода, и объект был сгенерирован как 3 единицы

Очевидно, что вариант 2 выглядит лучше:

__cxx_global_var_init:                  # @__cxx_global_var_init
        push    rbp
        mov     rbp, rsp
        movabs  rdi, offset bar
        call    foo::foo() [base object constructor]
        pop     rbp
        ret
foo::foo() [base object constructor]:  # @foo::foo() [base object constructor]
        push    rbp
        mov     rbp, rsp
        mov     qword ptr [rbp - 8], rdi
        mov     rdi, qword ptr [rbp - 8]
        mov     byte ptr [rdi], 1
        mov     byte ptr [rdi + 1], 1
        mov     byte ptr [rdi + 2], 1
        pop     rbp
        ret
_GLOBAL__sub_I_example.cpp:             # @_GLOBAL__sub_I_example.cpp
        push    rbp
        mov     rbp, rsp
        call    __cxx_global_var_init
        pop     rbp
        ret
bar:
        .zero   3

bar2:
        .byte   1                       # 0x1
        .byte   1                       # 0x1
        .byte   1                       # 0x1

Однако использование -O1 сокращает код без разницы:

bar:
        .byte   1                       # 0x1
        .byte   1                       # 0x1
        .byte   1                       # 0x1

bar2:
        .byte   1                       # 0x1
        .byte   1                       # 0x1
        .byte   1                       # 0x1

При использовании foo в качестве типа в программе генерируется ctor дляоба случая -O0 и -O1 (один и тот же ctor для каждого случая, разные для уровня оптимизации).См .: https://godbolt.org/z/0il6ou

А для -O2 объекты растворяются.

...