Как-то в комментариях VladD поделился информацией, что один из его коллег, сетевой программист, перешел от многопоточного к асинхронному сетевому программированию. Хотелось бы на примере конкретной задачи разобраться, насколько асинхронность выиграет у многопоточности.
Задача: возьмем один из простых сетевых протоколов - RFB. Нам нужно одновременно подключиться к 10 000 серверов с RFB на борту, и узнать версию RFB.
Как это реализовать многопоточно - я знаю, но как это реализовать асинхронно? И на сколько, в данной задаче, асинхронность выиграет? Сама реализация RFB - не нужна, нужен пример выполнения 10 000 одновременных асинхронных запросов.
Протестировал 3 варианта кода:
Многопоточный (поменял разбивку списка на несколько - на потокобезопасную очередь, чтобы уровнять шансы)
Асинхронный
Асинхронный (паттерн
Throttling)
Результаты (проверка 300 000 IP адресов):
- Многопоточный: 3 минуты 18 секунд
- Асинхронный: 1 минута 27 секунд
- Асинхронный (паттерн
Throttling): когда перевалило за 6 минут - закрыл программу и не стал измерять дальше. Скорости можно добиться только использовав в уровне параллелизма - размер всего списка, но тогда теряется смысл самого использования паттерна. Т.е. реализация отandreycha, если использовать уровень параллелизма меньше размера списка - работает дольше чем даже многопоточная версия. Возможно это простомояошибка, либо ошибкаandreycha.
Вывод:
- Стандартная асинхронная реализация работает более чем в 2 раза быстрее чем многопоточная.