Обновление: 2009-05-29
Спасибо за все предложения и советы. Я воспользовался вашими предложениями, чтобы мой рабочий код выполнялся в среднем в 2,5 раза быстрее, чем мой лучший результат пару дней назад. В итоге я смог сделать Java-код быстрее всего.
Уроки:
Мой пример кода ниже показывает вставку примитивных целых, но рабочий код на самом деле хранит строки (мой плохой). Когда я исправил это, время выполнения питона изменилось с 2,8 секунды до 9,6. Так что сразу же, Java был на самом деле быстрее при хранении объектов.
Но это не останавливается там. Я выполнял Java-программу следующим образом:
java -Xmx1024m SpeedTest
Но если вы установите начальный размер кучи следующим образом, вы получите огромное улучшение:
java -Xms1024m -Xmx1024m SpeedTest
Это простое изменение сократило время выполнения более чем на 50%. Таким образом, окончательный результат для моего SpeedTest составляет 9,6 секунды. Java 6,5 секунд.
Оригинальный вопрос:
У меня был следующий код Python:
import time
import sys
def main(args):
iterations = 10000000
counts = set()
startTime = time.time();
for i in range(0, iterations):
counts.add(i)
totalTime = time.time() - startTime
print 'total time =',totalTime
print len(counts)
if __name__ == "__main__":
main(sys.argv)
И он запустился примерно за 3,3 секунды на моей машине, но я хотел сделать это быстрее, поэтому я решил запрограммировать его на Java. Я предположил, что поскольку java компилируется и, как правило, считается более быстрым, чем python, я бы увидел большие окупаемости.
Вот код Java:
import java.util.*;
class SpeedTest
{
public static void main(String[] args)
{
long startTime;
long totalTime;
int iterations = 10000000;
HashSet counts = new HashSet((2*iterations), 0.75f);
startTime = System.currentTimeMillis();
for(int i=0; i<iterations; i++)
{
counts.add(i);
}
totalTime = System.currentTimeMillis() - startTime;
System.out.println("TOTAL TIME = "+( totalTime/1000f) );
System.out.println(counts.size());
}
}
Так что этот код Java делает в основном то же самое, что и код Python. Но он выполняется за 8,3 секунды вместо 3,3.
Я извлек этот простой пример из реального примера, чтобы упростить вещи. Критическим элементом является то, что у меня есть (set или hashSet), который заканчивается множеством членов, как в примере.
Вот мои вопросы:
Почему моя реализация на python быстрее, чем моя реализация на Java?
Есть ли лучшая структура данных для использования, чем hashSet (java) для хранения уникальной коллекции?
Что бы ускорить реализацию Python?
Что бы ускорить реализацию Java?
UPDATE:
Спасибо всем, кто внес свой вклад. Пожалуйста, позвольте мне добавить некоторые детали.
Я не включил свой производственный код, потому что он довольно сложный. И будет генерировать много отвлечения. Случай, который я представляю выше, является максимально упрощенным. Под этим я подразумеваю, что вызов java put кажется намного медленнее, чем add () набора python.
Реализация производственного кода на Java также примерно в 2,5 - 3 раза медленнее, чем в версии Python, как и выше.
Меня не беспокоит разогрев или запуск виртуальной машины. Я просто хочу сравнить код моего startTime с моим totalTime. Пожалуйста, не занимайтесь другими вопросами.
Я инициализировал хэш-набор с более чем достаточным количеством сегментов, чтобы его никогда не приходилось перефразировать. (Я всегда буду заранее знать, сколько элементов в конечном итоге будет содержать коллекция.) Полагаю, можно утверждать, что я должен был инициализировать его до итераций / 0.75. Но если вы попробуете это, вы увидите, что время выполнения не сильно изменится.
Я установил Xmx1024m для любопытных (на моей машине 4 ГБ оперативной памяти).
Я использую версию Java: среда выполнения Java (TM) SE (сборка 1.6.0_13-b03).
В рабочей версии я храню строку (2-15 символов) в hashSet, поэтому я не могу использовать примитивы, хотя это интересный случай.
Я запускал код много-много раз. Я очень уверен, что код Python в 2,5-3 раза быстрее, чем код Java.