Выбрать главу

  end

end

# Создайте перевернутый список из 30 тысяч элементов.

list = (1..30000).to_a.reverse

# Отсортируйте его, а затем распечатайте его голову и хвост select_sort(list)

p list[0...10]

p list[-10..-1]

В этом примере уже показаны некоторые интересные особенности Crystaclass="underline"

• Прежде всего, он относительно небольшой. Основной алгоритм состоит всего из четырех строк.

• Это выразительно. Вы можете перебирать списки со специализированными блоками или использовать диапазоны.

• Не существует единого обозначения типа. Вместо этого компилятор выводит каждый тип, включая аргумент метода.

Удивительно, но этот же код действителен и в Ruby. Воспользовавшись этим, если мы возьмем этот файл и запустим его как Ruby Selection_sort.cr (обратите внимание, что Ruby не заботится о расширениях файлов), это займет около 30 секунд. С другой стороны, выполнение этой программы после ее компиляции с помощью Crystal в оптимизированном режиме занимает около 0,45 секунды, то есть в 60 раз меньше. Конечно, эта разница не одинакова для любой программы. Это зависит от того, с какой рабочей нагрузкой вы имеете дело. Также важно отметить, что Crystal требуется время для анализа, компиляции, при необходимости оптимизации и создания собственного исполняемого файла.

На следующем графике показано сравнение этого алгоритма сортировки выбором, написанного для разных языков. Здесь вы можете видеть, что Crystal соревнуется на вершине, проигрывая C и очень близко приближаясь к Go. Важно отметить, что Crystal — безопасный язык: он имеет полную поддержку обработки исключений, отслеживает границы массивов, чтобы избежать небезопасного доступа, а также проверяет переполнение при целочисленных математических операциях. С другой стороны, C — небезопасный язык, и он ничего из этого не проверяет. Безопасность достигается за счет незначительного снижения производительности, но, несмотря на это, Crystal остается очень конкурентоспособным:

Сортировка выбором в перевернутом списке из 30 тыс. элементов

Рисунок 1.2. Сравнение реализации простой сортировки выбором на разных языках.

Примечание

Сравнение различных языков и сред выполнения в таких синтетических тестах, как этот, не отражает реальную производительность. Правильное сравнение производительности требует более реалистичной задачи, чем сортировка выбором, и широкого обзора кода экспертами по каждому языку. Тем не менее, разные проблемы могут иметь очень разные характеристики производительности. Итак, рассмотрите возможность сравнительного анализа для вашего варианта использования. В качестве справочного материала для комплексного теста можно изучить тесты TechEmpower Web Framework (https://www.techempower.com/benchmarks).

Сравнение веб-серверов

Crystal не только отлично подходит для выполнения вычислений в небольших случаях, но также хорошо работает в более крупных приложениях, таких как веб-сервисы. Язык включает в себя богатую стандартную библиотеку со всем понемногу, и вы узнаете о некоторых ее компонентах в Главе 4 «Изучение Crystal посредством написания интерфейса командной строки». Например, вы можете создать простой HTTP-сервер, например этот:

require "http/server"

server = HTTP::Server.new do |context|

  context.response.content_type = "text/plain"

  context.response.print "Hello world, got #{context

    .request.path}!"

end

puts "Listening on http://127.0.0.1:8080"

server.listen(8080)

Первая строка require "http/server” импортирует зависимость из стандартной библиотеки, которая становится доступной как HTTP::Server. Затем он создает сервер с некоторым кодом для обработки каждого запроса и запускает его на порту 8080. Это простой пример, поэтому у него нет маршрутизации.

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

Запросов в секунду на одном ядре

Рисунок 1.3 – Сравнение скорости запросов в секунду простых HTTP-серверов на разных языках

Здесь мы видим, что Crystal значительно опережает многие другие популярные языки (очень близкие к Rust и Go), а также является очень высокоуровневым и удобным для разработчиков. Многие языки достигают производительности за счет использования низкоуровневого кода, но при этом не требуется жертвовать выразительностью или раскрывать абстракции. Код Crystal легко читать и развивать. Та же тенденция наблюдается и в других приложениях, а не только в веб-серверах или микробенчмарках.