Это не полный ответ, я не могу объяснить, почему на самом деле он работает быстрее в Java, чем в C ++; но я могу объяснить пару вещей, которые сдерживают производительность вашей версии C ++. Пожалуйста, не выбирайте этот ответ как правильный, если у кого-то есть реальное объяснение общей разницы в производительности.
Этот ответ обсуждался на мета и был согласован с тем, что оставить его в качестве частичного ответа временно - лучший вариант.
Во-первых, и самое главное, как уже упоминалось в комментариях, Java-код уже оптимизирован при его тестировании, тогда как в C ++ вы должны указывать уровень оптимизации в качестве аргумента командной строки (формировать визуальную студию и компилировать как выпуск), и хотя это имеет большое значение, в моих тестах Java все еще находится на вершине (все результаты внизу).
Но я хочу указать на серьезный недостаток в вашем тесте, который может показаться незначительным в данном конкретном случае, поскольку он не имеет большого значения, когда вы смотрите на цифры, но все же важен:
Операции ввода-вывода добавляют заметные задержки. Для точного сравнения времени выполнения вы должны исключить операции ввода-вывода из вашего таймера на обоих языках. Хотя в этом случае это не имеет большого значения, если один язык выполняет и функцию, и вывод во время работы таймера, а другой - только функцию, что делает весь ваш тест смещенным и бессмысленным.
Чтобы сделать его более эквивалентным версии Java, измените основную часть c ++ на
int main()
{
int* input = FindDuplicate::CreateTestCase(InputSize);
int result;
auto start = std::chrono::system_clock::now(); //clock start
result = FindDuplicate::FindDuplicateNaive(input, InputSize);
auto end = std::chrono::system_clock::now(); //clock end
std::chrono::duration<double> elapsed_seconds = end - start;
cout << "Output is: " << result << endl;
cout << "elapsed time: " << elapsed_seconds.count() << "s\n";
}
Обратите внимание, что по умолчанию консольный ввод / вывод C ++ (iostream, cin / cout) даже медленнее, чем мог бы быть, потому что синхронизация с консольным вводом / выводом C (stdio, scanf / printf) включена, чтобы программа не выполняла странные вещи, если используются и cout, и printf.
Здесь вы можете прочитать о производительности cout при выключенной синхронизации. Мало того, что вы использовали ввод-вывод внутри ограничений таймера, вы даже использовали его в режиме худшей производительности.
Вот мои результаты, которые, хотя и дают Java преимущество, показывают, сколько различий могут иметь определенные опции компиляции и манипуляции ввода-вывода в C ++ (для одного cout разница в среднем на 0,03 с при отключении синхронизации больше, чем это выглядит).
Все значения в секундах являются средними для 10 тестов.
1. Java print in timer 1.52s
2. Java 1.36s
3. C++ debug, cout in timer 11.78s
4. C++ debug 11.73s
5. C++ release, cout in timer 3.32s
6. C++ release cout syncronization off 3.29s
7. C++ release 3.26s
Я хочу, чтобы вы поняли, что из всех этих тестов единственные, из которых имеет смысл сравнение, это 1 с 6 и 2 с 7 . Все остальные (3, 4, 5) будут сравнивать, независимо от того, сколько раз вы повторяете тест.