В каких языках существуют аналоги goroutines в плане производительности и простоты?
Есть язык Go и в нем есть замечательные Goroutines. Я, например, написал простенькую программу, которая выполняет тысячи одновременных обращений к удаленным узлам, при этом похожая по функционалу программа на Java или другом языке, использующем нативные потоки ОС, жрала бы во много раз больше системных ресурсов (а программа на Go не грузит проц более, чем на 30% и то это на старом компе с запущенным браузером, эклипсом и прочей фигней и не особенно оптимизированная).
Язык Go, безусловно, предоставляет удобную и, похоже, уникальную, модель многопоточности (горутины+каналы), но, на мой взгляд, это все хорошее, что можно о нем сказать. Сам язык убогий, о чем написано довольно много статей.
Вопрос в том, есть ли реальные альтернативы горутинам в других языках в плане производительности и накладных расходов?
при этом похожая по функционалу программа на Java или другом языке, использующем нативные потоки ОС, жрала бы во много раз больше системных ресурсов
Это весьма поверхностное суждение из области "если бы да кабы"...
В некоторых случаях это так, а в других совершенно иначе.
P.S. Кстати, модель Go-рутин использует нативные потоки, и программа Go, даже вовсе не использующая параллелизм, тоже активно использует нативные потоки.
> Это весьма поверхностное суждение из области "если бы да кабы"...
В некоторых случаях это так, а в других совершенно иначе.
Случаи, безусловно, бывают разные, но, согласитесь, стоимость стандартных потоков, например, в JVM, значительно выше горутин. Там даже при ста потоках при вобщем-то небольшой вычислительной работе основная часть времени ЦП тратится на переключение между потоками. Плюс сами потоки жрут прилично памяти.
>P.S. Кстати, модель Go-рутин использует нативные потоки, и программа Go, даже вовсе не использующая параллелизм, тоже активно использует нативные потоки.
Ну это ясно, вообще, абсолютно любая программа их использует (самое меньшее - 1 стандартный поток, в котором она выполняется). Только вот в Go зачастую одна параллельная задача не равна одному системному потоку (их число явно ограничивается переменной GOMAXPROCS, которая по дефолту равна числу ядер, так что программа на го не может заюзать больше потоков, даже если там 1к горуцтин будет).
С JVM некорректно вообще сравнивать, если там есть исполняющая система, интерпретирующая байт-код. Сравнивать можно только с POSIX pthread_t. И там не такая уж большая проблема создать несколько сот потоков, и не так критически много они потребляют ресурсов: небольшой стек, а переключение контекста вообще копеечное.
Легкие потоки на уровне библиотек есть практически во всех современных языках. Для упомянутой вами JavaVirtualMachine это Akka-Skala. В Go потоки и каналы введены в синтаксис языка, что дает конструкцию 'select case', которую чрезвычайно трудно реализовать в библиотеках. Идеология Хоара Communicating_Secuential_Processeses полностью на уровне синтаксиса реализована в Erlang с тем отличием от Go, что потоки именованы и к ним можно обращаться лично(в Go именованы только каналы). Вы вполне можете написать свой диспетчер на libthreads и системных вызовах epoll, kqueue. Также конкретную задачу тысячи обращений к удаленным узлам можно реализовать простым циклом, что в сущности и происходит под капотом, и такое частное решение конкретной задачи всегда будет эффективней.