Решил тут сравнить производительность Java и Python в "большой" мультитредовости.
Задача: запустить 10000 тредов, каждый из которых тупо подождёт секунду и закроется. Выйти из системы.
Исходный уровень: совершенно не знаю, как это делается в Питоне и ничего сложнее мелких системных скриптов на нём не писал. На Java довольно плотное программирование около 2.5 лет в весьма крупном проекта, но с тредами сам на низком уровне не работал, только обработка уже запущенных процессов.
Питон: через
5 минут (буквально) копания в Гугле и тестов родил такое:
code python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import threading
import time
def proc(n):
time.sleep(1)
for i in xrange(10000):
threading.Thread(target=proc, name="t"+str(i), args=[i]).start()
Время работы скрипта -
42 секунды. Расход памяти или ресурсов процессора замечен не был.
Дальше начинается веселье. Я принялся за Java. Как сделать просто запуск тредов я так и не нашёл. Сделал запуск через шедулер. После серии экспериментов исходную задачу... так и не решил
Треды отрабатывают успешно, но основной процесс не завершается, а так и остаётся запущенным. Если проигнорировать на завершение и закрывать потоки вручную, то выходит код примерно такой:
code java
import java.io.IOException;
import java.io.PrintStream;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import static java.util.concurrent.TimeUnit.*;
{
public static void main
(String[] args
)
{
final int MAX=10000;
ScheduledFuture<?>[] t = new ScheduledFuture<?>[MAX];
for(int i=0; i<MAX; i++)
{
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
t[i] = scheduler.schedule(new test(i), 0, SECONDS);
}
for(int i=0; i<MAX; i++)
t[i].cancel(true);
}
int n;
public test(int _n)
{
n = _n;
}
public void run()
}
}
То есть - открываем 10000 тредов, не дожидаясь их завершения (всё равно не работает) тут же закрываем, выходим в систему принудительно.
Облом подстерёг после того, как с тестовых 10 тредов взял 1000. "Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread".
Никакие -Xms/Xmx/Xss не помогали. Рост потребления памяти замечен не был.
5000 - сработало. Время выполнения около
7 секунд.
Итого, неполноценно реализованный вариант на Java примерно втрое быстрее работающего как задумано на Питоне.
Теперь веселье - на тесты и эксперименты с Java ушло около
45 минут
...
Правда, не всё так радужно. Говорят, у Питона есть страшный Global Interpreter Lock, сильно снижающий эффективность тредов, но я пока недопонял, где на него нарываются
...
Кто-то предложит рабочее решение на Java? А то я выдохся