@kr_ilya

Почему простой цикл на c++ выполняется медленнее, чем на golang?

Цикл инкрементирующий значение переменной на C++
int main(){
    long long c = 0;
    for(long long i = 0; i < 1000000000; i++){
        c++;
    }
   
    return 1;
}


Аналогичный цикл на Go
package main
func main(){
	var f int64 = 0

	for i := 0; i < 1000000000; i++{
		f++
	}
}


Время выполнения, слева C++, справа Go
62af153f52ebe436798193.png

Как видно, время выполнения на плюсах почти 2 секунды, в то время как на Go около 300 мс.

В чем причина медлительности плюсов и как можно ускорить выполнение?

Версии компиляторов
62af164ead602925022681.png
  • Вопрос задан
  • 447 просмотров
Пригласить эксперта
Ответы на вопрос 4
@deliro
Да хотя бы потому что оптимизатор может выбросить цикл, посчитав его ненужным. Есть оптимизации, которые умеют цикл заменять прогрессией, а здесь цикл можно вовсе удалить, тк он не влияет ни на что
Ответ написан
Комментировать
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Вы сами в комментариях привели дизассемблированный код. Go по какой-то причине оптимизирует код лучше - тупо выкидывает весь ваш цикл.

Чтобы этого не было, можно ксорить не с константой, а с индексом i, например.
Ответ написан
Комментировать
mayton2019
@mayton2019
Bigdata Engineer
Судя по скриншоту это windows. Если вы делаете бенчмарки под windows - то нужно правильно мерять время. Скорее всего вы меряли не время цикла а время запуска windows процесса + время цикла. Вместе с статическими конструкторами. И эти конструкторы в go оказались удачнее.

Короче вы не втом месте включали секундомер. А то так можно и доказать что PHP быстрее чем C++.
Ответ написан
@kr_ilya Автор вопроса
С добавлением полезной нагрузки в цикл и флага оптимизации -O2 при компиляции на плюсах получились такие результаты
c++
#include <iostream>
#include <chrono>

int main(){
    auto start_time = std::chrono::steady_clock::now();
    long long c = 0;
    for(long long i = 0; i < 1000000000; i++){
        c+=c xor i;
    }

    auto end_time = std::chrono::steady_clock::now();
    auto elapsed_ns = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
    std::cout << elapsed_ns.count() << " ms\n";
    std::cout << c << std::endl;
    return 1;
}


go
package main

import (
	"fmt"
	"time"
)

func main(){
	var f int64 = 0
	var i int64 = 0
	start := time.Now()

	for i = 0; i < 1000000000; i++{
		f+=f ^ i
	}
	duration := time.Since(start)

	fmt.Println(duration)
	fmt.Println(f)
}


lvh4se1gzwjezybvbpaztmwisme.png

Всё дело в оптимизации
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы