Привет тебе, дорогой %UserName%.
Многие из нас задумывались, какой язык более производительный. Услышав очередной разговор о том, что Java медленная, мне стало интересно посмотреть сравнение производительности Java, C++ и С#. Очевидно, что С++ будет самым производительным, но мне интереснее узнать, какова разница в производительности у С# и Java, и сколько они проигрывают С++. Всем, кому интересно прошу под кат.
Сравнивать языки программирования будем на классической задаче – сортировке массива. Сортировать будем алгоритмом быстрой сортировки. Каждую функцию будем прогонять на одинаковых массивах размером от 10000 до 100000 с шагом в 1000, и для точных результатов будем вызывать одну и ту же функцию на одном и том же массиве 20 раз.
Все расчёты проходили на процессоре Intel 3770K с тактовой частотой 3,5ГГц под управлением Windows 8.1. Компилятор С++ и С# — .Net framework 4.5.1. Компилятор Java – javac 1.7.0_45. Разумеется программы компилировались в режиме «Release», запускались по 15 раз прежде чем получить данные выходные файлы.
Исходные массивы, можете скачать здесь.
Исходник на Java
import java.io.*;
import java.util.StringTokenizer;
publicclassSort {publicstaticvoid main(String[] args) throws IOException {
FileReader inputStream = new FileReader("input.txt");
BufferedReader inputTxt = new BufferedReader(inputStream);
FileOutputStream myFile = new FileOutputStream("Java time.txt");
PrintWriter txtFile = new PrintWriter(myFile);
txtFile.println("Size\tTime");
int N = 20;
for (int i = 10000; i <= 100000 ; i += 1000) {
long averageTime = 0;
int[] array = parseStringToIntArray(inputTxt.readLine());
for (int j = 0; j < N; j++) {
int[] copyArray = array.clone();
long afterSort;
long beforeSort = System.nanoTime();
sortArrayByHoarMiddle(copyArray, 0, i - 1);
afterSort = System.nanoTime();
averageTime += (afterSort - beforeSort) / N;
}
txtFile.println(i + "\t" + averageTime);
}
inputTxt.close();
txtFile.close();
}
staticvoid sortArrayByHoarMiddle(int[] array, int i_n, int i_k) {
int i = i_n;
int j = i_k;
int k = (i + j) / 2;
int x = array[k];
do {
while (array[i] < x) {
i++;
}
while (x < array[j]) {
j--;
}
if (i <= j) {
int p = array[i];
array[i] = array[j];
array[j] = p;
i++;
j--;
}
} while (!(i > j));
if (i_n < j) {
sortArrayByHoarMiddle(array, i_n, j);
}
if (i < i_k) {
sortArrayByHoarMiddle(array, i, i_k);
}
}
staticint[] parseStringToIntArray(String str) {
StringTokenizer tokenizer = new StringTokenizer(str, " ");
int[] array = newint[tokenizer.countTokens()];
int i = 0;
while (tokenizer.hasMoreTokens()){
array[i] = Integer.parseInt(tokenizer.nextToken());
i++;
}
return array;
}
}
Как и ожидалось, С++ показал лучшие результаты. Что касается борьбы между C# и Java – то очевидно, что Java выигрывает более чем в два раза у C#. К сожалению, я не могу ответить на вопрос, почему так сильно проигрывает C#, если кто-нибудь знает, напишите – буду благодарен.
C# разрабатывался как язык программирования прикладного уровня для CLR и, как таковой, зависит, прежде всего, от возможностей самой CLR. Это касается, прежде всего, системы типов C#, которая отражает BCL. Присутствие или отсутствие тех или иных выразительных особенностей языка диктуется тем, может ли конкретная языковая особенность быть транслирована в соответствующие конструкции CLR. Так, с развитием CLR от версии 1.1 к 2.0 значительно обогатился и сам C#; подобного взаимодействия следует ожидать и в дальнейшем. (Однако, эта закономерность была нарушена с выходом C# 3.0, представляющего собой расширения языка, не опирающиеся на расширения платформы .NET.) CLR предоставляет C#, как и всем другим .NET-ориентированным языкам, многие возможности, которых лишены «классические» языки программирования. Например, сборка мусора не реализована в самом C#, а производится CLR для программ, написанных на C# точно так же, как это делается для программ на VB.NET, J# и др.
Странное сравнение, исходники совершенно разные, хотя бы тот факт, что StringTokenizer работает совершенно не так, как Split вас не смутил? Еще вы взяли буферизованный ридер для джавы, а для C# буферизацию не настроили.
Даже не сомневался, что под катом будет синтетический тест «100500 миллионов раз делаем какую-нибудь фигню и замеряем время». Надо пояснять, почему подобный тест вообще ниочём, или до меня уже всё сказано было?
комментарии (10)