LINUX.ORG.RU

Racket быстрее для многопоточной работы, чем Go

 , ,


5

6

Микрозамер скорости сервера эха: https://racket.discourse.group/t/racket-matching-or-exceeding-golang-for-echo-server-performance/660

Результаты:

Racket: ~114,584 сообщений/сек
Go (default): ~85,650 сообщений/сек
Go (GOMAXPROCS=1): ~108,495 сообщений/сек

Код для Racket (ссылка) использует потоки Racket (thread), код для Go (ссылка) использует горутины.

★★★★★

Finally I benchmarked it all with the load test using 3 threads simulating 3 clients which send messages as fast as they can for 180 seconds.

Асинхронный ввод/вывод не для таких сценариев нужен, вот если взять количество поток во много раз больше процессорных ядер, тогда интересно будет.

Ну для обработки одного сообщения, от его получения до отправки, в случае Racket не должно происходить ни одного переключения потоков, если я правильно догадываюсь как Racket работает, а у Go - из-за NxM модели, такие переключения вполне вероятны.

Begemoth ★★★★★
()
Последнее исправление: Begemoth (всего исправлений: 1)
Ответ на: комментарий от Begemoth

если взять количество поток во много раз больше процессорных ядер, тогда интересно будет

Тогда в Racket придётся вручную потоки между ядрами делить. Неинтересно.

monk ★★★★★
() автор топика

Главная фишка Go не в умопомрачительной скорости, а в богатой стандартной библиотеке (33 примитивных строки в Go, из которых минимум 2 лишние vs. 108 шпагетти в ракете).

Про «ракету» когда-то может быть и слышал, но что это такой за быстрый зверь, я не в курсе.

beastie ★★★★★
()
Ответ на: комментарий от LamerOk

Классика лисперов.

Классика ламерков :-) Лол :-)

anonymous
()
Ответ на: комментарий от beastie

108 шпагетти в ракете

Там 90% относится не к задаче, а к отладке вокруг неё (создание объекта, хранение списка потоков, старт по кнопке с клавиатуры, ручная обработка ошибок и освобождения ресурсов и прочее).

Полный аналог кода на Го:

#lang racket
(define host "localhost")
(define port 11777)
(define server (tcp-listen port 4 #f host))
(log-info "Server is running on: ~a:~a\n" host port)
(for ()
  (define-values (in out) (tcp-accept server))
  (thread (lambda ()
    (copy-port in out))))
monk ★★★★★
() автор топика
Ответ на: комментарий от beastie

Главная фишка Go не в умопомрачительной скорости, а в богатой стандартной библиотеке

Как раз стандартная библиотека у Racket очень богатая. От переносимого (Lin/Win/Mac) GUI до веб-сервера. Претензии всегда были только к скорости выполнения (всё-таки динамический язык со сборкой мусора и исключениями очень быстрым быть не может).

monk ★★★★★
() автор топика
Ответ на: комментарий от Begemoth

в случае Racket не должно происходить ни одного переключения потоков, если я правильно догадываюсь как Racket работает,

Да, в Racket все потоки внутри одного системного процесса (есть механизм использования дополнительных процессов, но надо явно указывать сколько процессов запускать и в каком процессе создавать поток).

а у Go - из-за NxM модели, такие переключения вполне вероятны.

Даже с GOMAXPROCS=1 ?

monk ★★★★★
() автор топика

если нужна производительность, то очевидно что эхо-сервер надо писать по-другому (как минимум не создавать по горутине на каждое соединение). А если производительность не нужна, то нафига она тут измеряется?

Lrrr ★★★★★
()

ну все, го стал теперь не нужен. а раст обгоняет уже?

umren ★★★★★
()
Ответ на: комментарий от monk

Да, в Racket все потоки внутри одного системного процесса

в любом языке все потоки внутри одного системного процесса, это от ОС зависит, а не от языка

anonymous
()
Ответ на: комментарий от Lrrr

А если производительность не нужна, то нафига она тут измеряется?

Сравниваем производительность горутин и потоков Racket на примере.

monk ★★★★★
() автор топика
Ответ на: комментарий от anonymous

в любом языке все потоки внутри одного системного процесса, это от ОС зависит, а не от языка

Хорошо, внутри одного системного потока.

monk ★★★★★
() автор топика
Ответ на: комментарий от anonymous

«Тогда в Racket придётся вручную потоки между ядрами делить. Неинтересно.»

Так это, наоборот, повышает управляемость. Можно точно указать, какие данные должны быть внутри одного системного потока (то есть не прыгать между ядрами), а какие должны быть разделяемые. При этом внутренних потоков может быть намного больше системных (как и в Go, но там как раз распределением горутин по системным потокам управлять почти нельзя).

monk ★★★★★
() автор топика
Ответ на: комментарий от monk

И тем не менее, целесообразность существования Go* ускользает.

* за пределами гугла

untitl3d
()
Последнее исправление: untitl3d (всего исправлений: 1)
Ответ на: комментарий от Lrrr

Как раз надо, Go делался дела того чтобы такая модель ничего не стоила.

Другое дело что там наворотили кроме этого. Подозреваю какой-то быдлокод, иначе Racket бы не обогнал.

vertexua ★★★★★
()

Go сильно проще. Любой макак с JS бекграундом его осилит. Racket это какое-то дрочево ради дрочева.

anonymous
()
Ответ на: комментарий от monk

в яндексовом userver ЕМНИП вообще выделяется по 200К на корутину. Советую запилить аналогичный бенчмарк с ним и написать в заголовке «Racket быстрее чем C++ для многопоточной работы», у тебя явно хватит ума для такого :))

Lrrr ★★★★★
()

Вот опять одно и то же, бенчмаркают хрен пойми что. Хоть бы нагрузили чем-то условно-полезным типа «считаем хеш строки», а не просто копированием десятка байт из входа на выход.

Dark_SavanT ★★★★★
()

Да-да, прямо все бросились из-за разницы в синтетике на уровне погрешности писать на скобках.

slovazap ★★★★★
()
Последнее исправление: slovazap (всего исправлений: 1)
Ответ на: комментарий от slovazap

на уровне погрешности писать на скобках.

В цепепе хоть строчку в компайл-тайме уже можно сгеренировать или эта фича ещё на рассмотрении комитета? :-)

anonymous
()
Ответ на: комментарий от anonymous

В цепепе хоть строчку в компайл-тайме уже можно сгеренировать или эта фича ещё на рассмотрении комитета? :-)

Шта?

anonymous
()
Ответ на: комментарий от untitl3d

constexpr не проходил еще?

А ты проходил уже? :-) Тогда показывай как выглядит конкатенация «Cepepe»+20+«kokoko!» в один литерал на constexpr :-) Конечный ассерт должен быть static_assert(sizeof(result)==15) :-) Покажи силу современного цепепе :-)

anonymous
()
Ответ на: комментарий от anonymous

Go сильно проще. Любой макак с JS бекграундом его осилит. Racket это какое-то дрочево ради дрочева.

Да ладно. Racket студенты осиливают.

monk ★★★★★
() автор топика
Ответ на: комментарий от Dark_SavanT

бенчмаркают хрен пойми что

Запуск потоков.

Хоть бы нагрузили чем-то условно-полезным типа «считаем хеш строки»

Тогда бы это был уже замер скорости хеширования.

monk ★★★★★
() автор топика
Ответ на: комментарий от olelookoe

Testing with many more, > 2000 clients, causes both echo servers to crash.

When running many clients for a period of time, io_uring_echo_server becomes unresponsive in an uninterruptible sleep state.

C во всей красе. Зато быстро. :-)

monk ★★★★★
() автор топика
Ответ на: комментарий от anonymous
template <typename _CharT>
class basic_string {
  using chr_t = _CharT;

  chr_t const *data_;
  std::size_t size_;

public:
  template <std::size_t N>
  constexpr basic_string(chr_t const (&data)[N])
      : data_(data), size_(N - 1) {}
  constexpr basic_string(chr_t const *data, std::size_t size)
      : data_(data), size_(size) {}

  constexpr basic_string(const basic_string &) noexcept = default;
  constexpr basic_string &operator=(const basic_string &) noexcept = default;

  constexpr std::size_t size() const { return size_; }

  constexpr chr_t operator[](std::size_t i) const { return data_[i]; }

  constexpr bool operator==(basic_string other) const {
    if (size_ != other.size_)
      return false;
    for (std::size_t i = 0; i < size_; ++i)
      if (data_[i] != other.data_[i])
        return false;
    return true;
  }

  constexpr bool operator<(const basic_string &other) const {
    unsigned i = 0;
    while (i < size() && i < other.size()) {
      if ((*this)[i] < other[i]) {
        return true;
      }
      if ((*this)[i] > other[i]) {
        return false;
      }
      ++i;
    }
    return size() < other.size();
  }

  constexpr const chr_t *data() const { return data_; }
  constexpr const chr_t *begin() const { return data(); }
  constexpr const chr_t *end() const { return data() + size(); }
};

using string = basic_string<char>;
fluorite ★★★★★
()
Ответ на: комментарий от Aber

То про обычный лисп, а у этого официальное имя было (((racket))).

monk ★★★★★
() автор топика
Ответ на: комментарий от fluorite

Теперь осталось показать как этой простынью сконкатенировать в компайл-тайме литерал «Cepepe»+20+":-)" :-) Лол :-)

anonymous
()

всё, теперь я уверен - Racket - лучшая среда для ECHO ! Даже лучше чем Go

надо будет написать еcho сервер, обязательно возьму :-)

MKuznetsov ★★★★★
()
Ответ на: комментарий от monk

Была же вроде новость, что собирались по умолчанию сделать в Racket традиционный синтаксис по умолчанию, а не S-expr. Что там с тех пор случилось?

theNamelessOne ★★★★★
()
Последнее исправление: theNamelessOne (всего исправлений: 1)
Ответ на: комментарий от theNamelessOne

собирались по умолчанию сделать в Racket традиционный синтаксис

Собирались. Основная проблема: надо переписать всю документацию. Пока кончилось тем, что «традиционный синтаксис» назвали языком Rhombus и выделили в отдельный проект: https://github.com/racket/rhombus-prototype

monk ★★★★★
() автор топика

HTTP бенч показывает невероятно узкую часть перформанса языка. В этом коде только открытие сокета и проброс колбека на запрос. Плюс немного магии с http заголовком. Стоит ещё отметить, что конкретно для Go использование стандартного http сервера совсем не показатель языка. Достаточно посмотреть тот же fasthttp библиотеку. Она до 10 раз быстрее стандартной либы. Какие в этом случае делать выводы о ракете и голэнге?😄

ergo ★★★
()

Приложения разработанные на Racket можно ли использовать на другой машине где не установлен Racket? Нужно ли на целевой машине наличие полностью установленного дистрибутива Racket, или достаточно какой-то минимальной части для запуска приложения?

Т.е написал я приложения на Ракете, запихал в дистрибутив приложения нужные библиотеки, и передал на другой комп без полной установки Ракеты. Это возможно?

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.