Я бы в любой день взял прирост производительности в 2-3 раза.
Резюме
И вот оно: одновременная обработка нескольких входных файлов! Параллельное программирование может быть ценным инструментом для создания высокопроизводительных приложений, позволяя разбивать рабочие нагрузки, связанные с IO, так, чтобы некоторая часть работы выполнялась постоянно. Кроме того, его можно использовать для уменьшения объема памяти приложения за счет одновременной обработки входных данных по мере их поступления, без необходимости ждать и загружать все данные в память.
На данный момент наш CLI почти готов! Теперь он может эффективно обрабатывать как одиночные, так и множественные входные файлы. Он может передавать данные в потоковом режиме, чтобы уменьшить использование памяти, и настроен для простой поддержки использования библиотек. Далее мы собираемся сделать что-то немного другое: мы собираемся поддерживать отправку уведомлений на рабочем столе о различных событиях в нашем CLI. Для этого в следующей главе мы узнаем о способности Crystal связываться с библиотеками C.
7. Совместимость c C
В этой главе основное внимание будет уделено одной из наиболее продвинутых функций Crystaclass="underline" возможности взаимодействия с существующими библиотеками C путем написания привязок C. Эта функция Crystal позволяет повторно использовать высокооптимизированный и/или надежный код внутри Crystal, не написав ни строчки C и не беря на себя нетривиальную задачу по переносу всего этого в Crystal. Мы рассмотрим следующие темы:
• Знакомство с привязками C.
• Привязка libnotify
• Интеграция привязок
libnotify позволяет отправлять уведомления на рабочий стол в качестве средства предоставления пользователю ненавязчивой информации при возникновении событий. Мы собираемся использовать эту библиотеку для отправки собственных уведомлений.
К концу этой главы вы сможете писать привязки C для существующих библиотек и понимать, как лучше всего скрыть детали реализации привязок от конечного пользователя. Привязки C позволяют коду Crystal использовать высокооптимизированный код C или просто разрешать повторное использование кода без необходимости предварительного переноса всей библиотеки в Crystal.
Технические требования
Требования к этой главе следующие:
• Рабочая установка Кристалла.
• Рабочая установка jq.
• Рабочая установка libnotify.
• Рабочий компилятор C, например GCC.
Инструкции по настройке Crystal можно найти в Главе 1 «Введение в Crystal». Последние версии jq, libnotify и GCC, скорее всего, можно установить с помощью менеджера пакетов в вашей системе, но их также можно установить вручную, загрузив их с https://stedolan.github.io/jq/download, https://gitlab. gnome.org/GNOME/libnotify и https://gcc.gnu.org/releases.html соответственно. Если вы работаете с этой главой в ОС, отличной от Linux, например, macOS или Windows/WSL, то все может работать не так, как ожидалось, если вообще работать.
Все примеры кода, использованные в этой главе, можно найти в папке главы 7 на GitHub: https://github.com/PacktPublishing/Crystal-Programming/tree/main/Chapter07.
Вводим привязки на языке C
Написание привязок C предполагает использование некоторых конкретных ключевых слов и концепций Crystal для определения API библиотеки C, например, какие функции она имеет, каковы аргументы и какой тип возвращаемого значения. Затем Crystal может использовать эти определения, чтобы определить, как их использовать. Конечным результатом является возможность вызывать функции библиотеки C из Crystal без необходимости писать код C самостоятельно. Прежде чем мы углубимся непосредственно в привязку libnotify, давайте начнем с нескольких более простых примеров, чтобы представить концепции и тому подобное. Возьмем, к примеру, этот простой файл C:
#include <stdio.h>
void sayHello(const char *name)
{
printf("Hello %s!\n", name);
}
Мы определяем одну функцию, которая принимает указатель char, представляющий имя человека, с которым можно поздороваться. Затем мы можем определить наши привязки:
@[Link(ldflags: "#{ DIR }/hello.o")]
lib LibHello
fun say_hello = sayHello(name : LibC::Char*) : Void
end
LibHello.say_hello "Bob"