Обновление: 2009-05-29
Спасибо за все предложения и советы. Я использовал ваши предложения, чтобы сделать мой производственный код в 2,5 раза быстрее, чем мой лучший результат, пару дней назад.. В конце концов, я смог сделать код Java самым быстрым.
Уроки:
-
В моем примере ниже показана вставка примитивных int, но производственный код на самом деле хранит строки (мой плохой). Когда я исправил, что время выполнения python перешло с 2.8 секунд до 9.6. Таким образом, сразу с места в пути, ява была фактически быстрее при хранении объектов.
-
Но это не останавливается на достигнутом. Я выполнял java-программу следующим образом:
java -Xmx1024m SpeedTest
Но если вы зададите начальный размер кучи следующим образом, вы получите огромное улучшение:
java -Xms1024m -Xmx1024m SpeedTest
Это простое изменение сократило время выполнения более чем на 50%. Итак, конечным результатом для моего SpeedTest является python 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, по-видимому, намного медленнее, чем набор().
Java-реализация производственного кода также примерно в 2,5 - 3 раза медленнее, чем версия python, как и выше.
Я не беспокоюсь о перегреве или запуске vm. Я просто хочу сравнить код с моего startTime с моим итоговым временем. Пожалуйста, не беспокойтесь о других вопросах.
Я инициализировал hashset с более чем достаточным количеством ведер, чтобы ему никогда не приходилось перефразировать. (Я всегда буду знать заранее, сколько элементов будет содержать коллекция.) Полагаю, можно утверждать, что я должен был инициализировать его итерациями /0.75. Но если вы попробуете, вы увидите, что время выполнения не сильно повлияло.
Я установил Xmx1024m для тех, кому было любопытно (моя машина имеет 4 ГБ оперативной памяти).
Я использую java-версию: Java (TM) SE Runtime Environment (build 1.6.0_13-b03).
В производственной версии я сохраняю строку (2-15 символов) в hashSet, поэтому я не могу использовать примитивы, хотя это интересный случай.
Я запускаю код много, много раз. У меня очень высокая уверенность в том, что код python находится в 2,5 и 3 раза быстрее, чем Java-код.