Ваш пример Java (Kotlin) не измеряет гранулярность наносекунды; в основном он измеряет, сколько времени занимает сборка списка объектов Long. (или разверните кучу, или выделите объекты и заголовки объектов - если вы выполните тест только один раз, он может попытаться собрать мусор, но он не будет успешным, пока работает цикл)
Java работает довольно быстро с выделением памяти, обычно быстрее, чем стандартные библиотеки выделения памяти для C / C ++.
Для C ++ возможно, что, по крайней мере, значительный процент воспринимаемой точности наносекундных часов поступает от вызова push_back
10 миллионов раз для вектора, который включает в себя ряд перераспределений.
Лучшим тестом был бы (Котлин, но то же самое можно сделать для C ++) - нет необходимости запоминать временные метки в списке, чтобы вычислить среднюю разницу между ними.
fun main(args: Array<String>) {
for (i in 0 until 10) {
runTest();
}
}
fun runTest() {
var lastTime = System.nanoTime()
var count = 0;
var total = 0L;
for (i in 0 until 50_000_000) {
val time = System.nanoTime()
if (time > lastTime) {
count++;
total += time - lastTime;
lastTime = time;
}
}
val result = total / count;
println("Average resolution: ${result}ns")
}
Примечание: это дает мне довольно последовательную точность 32-35 нс в Java, что намного лучше, чем 45-200 нс, которые дал мне ваш исходный код.
Что касается вашего кода C ++, ваш исходный код, работающий на моем MacBookPro, дает мне 68-78 нс (при запуске в цикле, который запускает его 10 раз)
Я также удалил ненужный вектор из вашего кода, а затем он дает результат 50-51 нс, что дает достойное указание на то, что реальная гранулярность составляет 50 нс.
JVM работает несколько лучше, чем 32-35 нс (на 38% лучше, чем 50 нс), но разница не настолько велика, как вы упомянули.
Пожалуйста, попробуйте еще раз и опубликуйте вывод с кодом, который не сохраняет результаты в списке без необходимости, поскольку это сильно влияет на результаты.
#include <iostream>
#include <chrono>
#include <numeric>
#include <vector>
int main1() {
using namespace std;
using namespace chrono;
vector<long long int> time_list;
long long total = 0;
int count = 0;
auto lastTime = duration_cast<nanoseconds>(high_resolution_clock::now().time_since_epoch()).count();
for(int i = 0; i < 50000000; ++i) {
auto time = duration_cast<nanoseconds>(high_resolution_clock::now().time_since_epoch()).count();
if (time > lastTime) {
count++;
total += time - lastTime;
lastTime = time;
}
}
long long result = total / count;
printf("Average resolution: %.2lld ns\n", result);
return 0;
}
int main() {
for (int i = 0; i < 10; i++) {
main1();
}
}