- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Crystal Programming. Введение на основе проекта в создание эффективных, безопасных и читаемых веб-приложений и приложений CLI - Джордж Дитрих
Шрифт:
Интервал:
Закладка:
def process_multiple(filter : String, input_files :
Array(String), error : IO) : Nil
input_files.each do |file|
File.open(file, "r") do |input_file|
File.open("#{input_file.path}.transformed", "w") do
|output_file|
self.process [filter], input_file, output_file, error
end
end
end
end
Этот метод сводится к следующим шагам:
1. Определите новый метод, предназначенный для обработки нескольких входных файлов, который принимает фильтр и массив файлов для обработки.
2. Переберите каждый входной файл, используя метод File.open, чтобы открыть файл для чтения.
3. Снова используйте File.open, чтобы открыть выходной файл для записи, используя путь к входному файлу с добавлением .transformed в качестве имени выходного файла,
4. Вызовите метод одиночного ввода, передав наш фильтр в качестве единственного аргумента и используя открытые файлы в качестве входных и выходных операций IO.
Прежде чем мы сможем это протестировать, нам нужно сделать так, чтобы передача опции --multi заставляла CLI вызывать этот метод. Давайте сделаем это сейчас. Откройте src/transform_cli.cr и обновите его, чтобы он выглядел следующим образом:
require "./transform"
require "option_parser"
processor = Transform::Processor.new
multi_file_mode = false
OptionParser.parse do |parser|
parser.banner = "Usage: transform <filter> [options]
[arguments] [filename …]"
parser.on("-m", "--multi", "Enables multiple file input mode") { multi_file_mode = true }
parser.on("-h", "--help", "Show this help") do
puts parser
exit
end
end
begin
if multi_file_mode
processor.process_multiple ARGV.shift, ARGV, STDERR
else
processor.process ARGV, STDIN, STDOUT, STDERR
end
rescue ex : RuntimeError
exit 1
end
И снова на помощь приходит стандартная библиотека Crystal в виде типа OptionParser. Этот тип позволяет вам настроить логику, которая должна выполняться, когда эти параметры передаются через ARGV. В нашем случае мы можем использовать это для определения более удобного интерфейса, который также будет поддерживать параметры -h или --help. Кроме того, он позволяет вам реагировать на флаг --multi без необходимости вручную анализировать ARGV. Код довольно прост. Если флаг передан, мы устанавливаем для переменной multi_file_mode значение true, которое используется для определения того, какой метод процессора вызывать.
Чтобы проверить это, я создал несколько простых файлов YAML в корневом каталоге проекта. Не имеет большого значения, что они собой представляют, важно лишь то, что они действительны в формате YAML. Затем я собрал наш двоичный файл и запустил его с помощью ./bin/transform --multi. file1.yml file2.yml file3.yml, утверждая, что три выходных файла были созданы должным образом. У меня это заняло ~0,1 секунды. Давайте посмотрим, сможем ли мы улучшить это, реализовав параллельную версию метода process_multiple.
Вспоминая то, что мы узнали в последних двух разделах, чтобы сделать этот метод параллельным, нам понадобится инициировать открытие файла и обрабатывать логику внутри волокна. Затем нам понадобится канал, чтобы мы могли отслеживать завершенные файлы. В конечном итоге метод должен выглядеть так:
def process_multiple(filter : String, input_files :
Array(String), error : IO) : Nil
channel = Channel(Bool).new
input_files.each do |file|
spawn do
File.open(file, "r") do |input_file|
File.open("#{input_file.path}.transformed", "w")
do |output_file|
self.process [filter], input_file, output_file, error
end
end
ensure
channel.send true
end
end
input_files.size.times do
channel.receive
end
end
По сути, это то же самое, только с введением волокон для параллельности. Назначение канала — гарантировать, что основное волокно не выйдет из строя до завершения обработки всех файлов. Это достигается путем отправки значения true в канал после обработки файла и получения этого значения ожидаемое количество раз. Команда send находится внутри блока ensure для обработки сценария в случае сбоя процесса. Эта реализация требует немного большей доработки и будет рассмотрена в следующей главе. Я провел тот же тест, что и раньше, с параллельным кодом и получил значение от 0,03 до 0,06 секунды.
Я бы в любой день взял прирост производительности в 2-3 раза.
Резюме
И вот оно: одновременная обработка нескольких входных файлов! Параллельное программирование может быть ценным инструментом для создания высокопроизводительных приложений, позволяя разбивать рабочие нагрузки, связанные с IO, так, чтобы некоторая часть работы выполнялась постоянно. Кроме того, его можно использовать для уменьшения объема памяти приложения за счет одновременной обработки входных данных по мере их поступления, без необходимости ждать и загружать все данные в память.
На данный момент наш CLI почти готов! Теперь он может эффективно обрабатывать как одиночные, так и множественные входные файлы. Он может передавать данные в потоковом режиме, чтобы уменьшить использование памяти, и настроен для простой поддержки использования библиотек. Далее мы собираемся сделать что-то немного другое: мы собираемся поддерживать отправку уведомлений на рабочем столе о различных событиях в нашем CLI. Для этого в следующей главе мы узнаем о способности Crystal связываться с библиотеками C.
7. Совместимость c C
В этой главе основное внимание будет уделено одной из наиболее продвинутых функций Crystal: возможности взаимодействия с существующими библиотеками C путем написания привязок C. Эта функция Crystal позволяет повторно использовать высокооптимизированный и/или надежный код внутри Crystal, не написав ни строчки C и не беря на себя нетривиальную задачу по переносу всего этого в Crystal. Мы рассмотрим следующие темы:
• Знакомство с привязками C.
• Привязка libnotify
• Интеграция привязок
libnotify позволяет отправлять уведомления на рабочий стол в качестве средства предоставления пользователю ненавязчивой информации при возникновении событий. Мы собираемся использовать эту библиотеку для отправки собственных уведомлений.
К концу этой главы вы сможете писать привязки C для существующих библиотек и понимать, как лучше всего скрыть детали реализации привязок от конечного пользователя. Привязки C позволяют коду Crystal использовать высокооптимизированный код C или просто разрешать повторное использование кода без необходимости предварительного переноса всей библиотеки в Crystal.
Технические требования
Требования к этой главе следующие:
• Рабочая установка Кристалла.
• Рабочая установка jq.
• Рабочая установка libnotify.
• Рабочий компилятор C, например GCC.
Инструкции по настройке Crystal можно найти в Главе 1 «Введение в