Пишу, по большей части, про историю, свою жизнь и немного про программирование.

PHP: FFI vs. exec

Нередко отсутствующую в ПХП функциональность наскоро заменяют вызовом утилит командной строки. И мне стало интересно взглянуть на досуге — может ли вызов через ffi (интерфейс к Си, который появился в ПХП 7.4) быть хорошей альтернативой.

Говорят, вызов через ffi работает очень медленно, такова природа этого способа (и мы это видим в других языках), это, конечно, очевидно, но медленно насколько?

Для сравнения была взята функция, создающая временный директорий по маске, которую я использовал в одной из заметок, и её аналог, использующий внешнюю утилиту:

$mkdtemp = function (string $template): string {
    $cmd = '/usr/bin/mktemp -d '.escapeshellarg($template);
    $dir = exec($cmd, $out, $ret);

    if ($ret === 0) {
        return $dir;
    } else {
        ['message' => $message, 'type' => $type] = error_get_last();
        throw new RuntimeException($message, $type);
    }
};

Весь код был обёрнут в цикл на 10000 итераций и запущен. Я провёл по десять запусков, а результат усреднил.

Создание директория через ffi заняло примерно 0,77 секунд на 10 тысяч итераций, а через утилиту командной строки — примерно 72,62 секунды на те же 10 тысяч итераций.

Конечно какое-то время занимает запуск интерпретатора и прочие расходы, но даже в этом случае разница более чем очевидна — запуск утилиты несомненно хуже.

3 комментария
Антон 2020

Было бы интересно сравнить результаты на меньшем (1, 10, 100, 1000) кол-ве итераций.

Евгений Степанищев 2020

Могу сделать, но 10 и меньше итераций, скорее всего, будет не показательно.

Евгений Степанищев 2020

Один:

FFI — 0,1 (сравнимо с пустым запуском)
Exec — 0,114 (сравнимо с пустым запуском)

Десять:

FFI — 0,1
Exec — 0,24

Сто:

FFI — 0,118
Exec — 0,735

Тысяча:

FFI — 0,183
Exec — 7,211

Антон 2020

Не пришло уведомление, сейчас увидел комментарий, спасибо!