Решил тут сравнить производительность Java и Python в "большой" мультитредовости.
Задача: запустить 10000 тредов, каждый из которых тупо подождёт секунду и закроется. Выйти из системы.
Исходный уровень: совершенно не знаю, как это делается в Питоне и ничего сложнее мелких системных скриптов на нём не писал. На Java довольно плотное программирование около 2.5 лет в весьма крупном проекта, но с тредами сам на низком уровне не работал, только обработка уже запущенных процессов.
Питон: через [b]5 минут[/b] (буквально) копания в Гугле и тестов родил такое:
#!/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. Как сделать просто запуск тредов я так и не нашёл. Сделал запуск через шедулер. После серии экспериментов исходную задачу... так и не решил :) Треды отрабатывают успешно, но основной процесс не завершается, а так и остаётся запущенным. Если проигнорировать на завершение и закрывать потоки вручную, то выходит код примерно такой:
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 class test implements Runnable { public static void main(String[] args) { final int MAX=10000;
ScheduledFuture<?>[] t = new ScheduledFuture<?>[MAX];
System.out.println("Init"); for(int i=0; i<MAX; i++) { ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); t[i] = scheduler.schedule(new test(i), 0, SECONDS); }
System.out.println("Stop"); for(int i=0; i<MAX; i++) t[i].cancel(true); System.exit(0); }
int n;
public test(int _n) { n = _n; }
public void run() try { Thread.sleep(1000); } catch(Exception e){} } }
То есть - открываем 10000 тредов, не дожидаясь их завершения (всё равно не работает) тут же закрываем, выходим в систему принудительно.
Облом подстерёг после того, как с тестовых 10 тредов взял 1000. "Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread".
Никакие -Xms/Xmx/Xss не помогали. Рост потребления памяти замечен не был.
5000 - сработало. Время выполнения около *7 секунд.*
Итого, неполноценно реализованный вариант на Java примерно втрое быстрее работающего как задумано на Питоне.
Теперь веселье - на тесты и эксперименты с Java ушло около *45 минут* :D
...
Правда, не всё так радужно. Говорят, у Питона есть страшный Global Interpreter Lock, сильно снижающий эффективность тредов, но я пока недопонял, где на него нарываются :)
...
Кто-то предложит рабочее решение на Java? А то я выдохся ;)