А что если я вот не хочу чтобы команда создавала и проверяла файлы?
Для этого пишут `.PHONY: ${target}`. Например у нас так объявлен таргет `run` и, даже если файл с названием `run` будет присутствовать в директории цель не будет выполняться.
description: Как встроить Rust в проект на Python.
position: 2
category: 'Python'
---
# Описание проблемы
Каким бы Python удобным не был, скоростью он похвастаться никак не может.
И для некоторых задач это достаточно критично.
Например, не так давно у меня была задача достать много информации
из файлов логов. Проблема в том, что один лог-файл занимает от 3-4 ГБ. А файлов
таких много и информацию достать требуется быстро. Изначальный вариант на Python
был написан за минут 15-20, но скорость его работы занимала 30-40 минут на один файл. После переписывания одной функции на Rust, скрипт отработал за 1 минуту.
Давайте напишем свой проект со встроенной функцией на Rust.
<br>
Задача проекта будет следующей:
Дан файл лога запросов на некоторый сервер. Требуется
найти количество запросов к определённому файлу и сумму переданных байт.
Для демонстрации мы напишем 2 функции, одна будет использовать наивное решение задачи на питоне,
Как можно видеть из кода, мы просто подсчитываем итоговое количество найденных файлов.
Посмотрим сколько времени займёт парсинг нашего сгенерированного файла.
```bash
$ time pyrust parser "test.log"
Found 1000 files
pyrust parser test.log 2443.42s user 2.10s system 99% cpu 40:59.30 total
```
Обработка данного файла заняла 40 минут. Это довольно печальный результат.
Самое время попробовать использовать Rust.
# Интеграция Rust
Для интеграции Rust в python код я буду использовать [PyO3](https://github.com/PyO3/pyo3) для биндингов и [maturin](https://github.com/PyO3/maturin) для сборки проекта.
Начнём с инициализации проекта и установки сборщика. В корневой папке проекта
создайте папку проекта с растом.
<b-message type="is-info" has-icon>
В теории можно использовать maturin как основной инструмент сборки проекта,
но это лишает вас всех прелестей poetry. Поэтому удобнее использовать Rust в
подпроекте и указать его как зависимость в списке зависимостей своего проекта.
</b-message>
```bash
$ cargo new --lib rusty_log_parser
```
Теперь создадим `pyproject.toml` и напишем туда описание нашего python пакета.
```toml{}[pyproject.toml]
[tool.poetry]
name = "rusty_log_parser"
version = "0.1.0"
description = "Log file parser with Rust core"
authors = ["Pavel Kirilin <win10@list.ru>"]
[build-system]
requires = ["maturin>=0.12,<0.13"]
build-backend = "maturin"
```
Также поправим `Cargo.toml`.
```toml{}[Cargo.toml]
[lib]
# Название модуля
name = "rusty_log_parser"
# Обязательный тип крейта, чтобы можно было использовать его
# в питоне.
crate-type = ["cdylib"]
[dependencies]
# Библиотека биндингов для питона.
pyo3 = { version = "0.15.1", features = ["extension-module"] }
# Библиотека для сплита. Повторяет функционал shlex.
shell-words = "1.0.0"
```
После этих нехитрых изменений попробуем собрать проект.
```shell
$ cd rusty_log_parser
$ cargo build
```
Теперь напишем сам парсер логов в Rust.
```rust{}[rusty_log_parser/src/lib.rs]
use std::collections::HashMap;
use std::fs::File;
use std::io;
use std::io::BufRead;
use pyo3::prelude::*;
/// Parse log file in rust.
/// This function parses log file and returns HashMap with Strings as keys and
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.