Какое присваивание быстрее по времени?

Рейтинг: 2Ответов: 1Опубликовано: 16.08.2023

Присваивание происходит так в C++(если я ошибаюсь - поправьте меня), задаём тип переменной, называем её и даём ей значение. Если у этого значения другой тип, то он меняется на тот, который задали. По итогу выглядит всё так:

<тип_переменной> <название_переменной> = <значение_переменной>

Меня интересует момент:

Если у этого значения другой тип, то он меняется на тот, который задали

Т.е.

#include <iostream>

int main()
{
    unsigned int a = 3.03;
    std::cout << a;
    return 0;
}

Выведет тип unsigned int и число 3. Но если бы я указал изначально 3, то присваивание произошло бы быстрее, чем изначальное? Вот ещё примеры:

#include <iostream>

int main()
{
    long long a = 30L; //long long a = 30
    double b = 3.0; //double b = 3
    short c = 9; //short c = 9.23
    bool d = true; //bool d = 1 (0 - это false)
    return 0;
}

Есть ли разница по времени, где я явно указываю, какой тип значения; с примерами после //. Или разницы нет?

Ответы

▲ 3Принят

Сыграем по вашим правилам. Первый код:

#include <iostream>

int main()
{
    unsigned int a = 3.03;
    std::cout << a;
    return 0;
}

Компиляция:

$ g++ -pedantic -Wall -Wextra -Werror -Wwrite-strings -Wconversion temp.cpp
temp.cpp: In function ‘int main()’:
temp.cpp:7:22: error: conversion from ‘double’ to ‘unsigned int’ changes value from ‘3.0299999999999998e+0’ to ‘3’ [-Werror=float-conversion]
    7 |     unsigned int a = 3.03;
      |                      ^~~~
cc1plus: all warnings being treated as errors

Ошибка. Компилятор с максимальным уровнем предупреждений и ошибок такой код отвергает: преобразование из double в unsigned int не законно. Понизим строгость:

$ g++ -pedantic -Wall -Wextra -Wwrite-strings -Wconversion temp.cpp
temp.cpp: In function ‘int main()’:
temp.cpp:7:22: warning: conversion from ‘double’ to ‘unsigned int’ changes value from ‘3.0299999999999998e+0’ to ‘3’ [-Wfloat-conversion]
    7 |     unsigned int a = 3.03;
      |                      ^~~~

Предупреждение есть, но компиляция прошла. Чтобы понять что там, получим ассемблерный код:

$ g++ -pedantic -Wall -Wextra -Wwrite-strings -Wconversion -S temp.cpp
temp.cpp: In function ‘int main()’:
temp.cpp:7:22: warning: conversion from ‘double’ to ‘unsigned int’ changes value from ‘3.0299999999999998e+0’ to ‘3’ [-Wfloat-conversion]
    7 |     unsigned int a = 3.03;
      |                      ^~~~

$ cat temp.s
...
main:
...
  movl    $3, -4(%rbp)
  movl    -4(%rbp), %eax
  movl    %eax, %esi
  movl    $_ZSt4cout, %edi
  call    _ZNSolsEj
...

В ассемблере нет константы 3.03 и нет преобразования double в unsigned int. Время на него не будет тратиться.

Как поменяется время компиляции?

Программа, которая создаёт программу, в которой сто тысяч переменных и сто тысяч преобразований из double в unsigned int:

#include <iostream>

int main() {
    std::cout << "int main() {\n";
    for (int i = 0; i < 100000; ++i) {
        std::cout << "    unsigned int a" << i << " = 3.03;\n";
    }
    std::cout << "}\n";
}
$ g++ temp.cpp && ./a.out > temp_.cpp

$ head temp_.cpp
int main() {
    unsigned int a0 = 3.03;
    unsigned int a1 = 3.03;
    unsigned int a2 = 3.03;
    unsigned int a3 = 3.03;
    unsigned int a4 = 3.03;
    unsigned int a5 = 3.03;
    unsigned int a6 = 3.03;
    unsigned int a7 = 3.03;
    unsigned int a8 = 3.03;

$ tail temp_.cpp
    unsigned int a99991 = 3.03;
    unsigned int a99992 = 3.03;
    unsigned int a99993 = 3.03;
    unsigned int a99994 = 3.03;
    unsigned int a99995 = 3.03;
    unsigned int a99996 = 3.03;
    unsigned int a99997 = 3.03;
    unsigned int a99998 = 3.03;
    unsigned int a99999 = 3.03;
}

$ time g++ temp_.cpp

real  0m24.953s
user  0m24.880s
sys   0m0.064s

Двадцать пять секунд. Теперь тоже самое но без double:

#include <iostream>

int main() {
    std::cout << "int main() {\n";
    for (int i = 0; i < 100000; ++i) {
        std::cout << "    unsigned int a" << i << " = 3;\n";
    }
    std::cout << "}\n";
}
$ g++ temp.cpp && ./a.out > temp_.cpp

$ head temp_.cpp
int main() {
    unsigned int a0 = 3;
    unsigned int a1 = 3;
    unsigned int a2 = 3;
    unsigned int a3 = 3;
    unsigned int a4 = 3;
    unsigned int a5 = 3;
    unsigned int a6 = 3;
    unsigned int a7 = 3;
    unsigned int a8 = 3;

$ tail temp_.cpp
    unsigned int a99991 = 3;
    unsigned int a99992 = 3;
    unsigned int a99993 = 3;
    unsigned int a99994 = 3;
    unsigned int a99995 = 3;
    unsigned int a99996 = 3;
    unsigned int a99997 = 3;
    unsigned int a99998 = 3;
    unsigned int a99999 = 3;
}

$ time g++ temp_.cpp

real  0m24.644s
user  0m24.564s
sys   0m0.072s

Снова двадцать пять секунд.

Вывод: "неправильный" тип не влияет на время выполнения программы, потому что не попадает в программу. "Неправильный" тип не влияет на время компиляции программы, потому что у компилятора много другой работы, на фоне которой разбор констант теряется.