PHP
Go

PHP から Go の関数を呼び出す

More than 3 years have passed since last update.

libffi を使って PHP から Go の関数を呼び出して速度を計測しました。


参考記事

RubyからGoの関数をつかう → はやい の記事に触発されて書きました。


システム要件


  • PHP 7.0

  • Go 1.5


libffi のインストール

Mac OS X の homebrew では次のコマンドでインストールできます。

brew install libffi


MFFI のインストール

PHP 7.0 であれば、MFFI を使うことができます。

git clone https://github.com/mgdm/MFFI.git

cd MFFI
phpize
./configure
make
make install
echo
extension=mffi.so > /usr/local/etc/php/7.0/conf.d/ext-mffi.ini

mffi エクステンションが読み込まれているか確認しましょう。

php -m | grep mffi

うまく読み込まれていない場合、設定ファイルを確認してみましょう。

php --ini


Go のコードから共有ライブラリ (so) を生成する

フィボナッチ数列を再帰関数で定義してみましょう。


fib.go

package main

import "C"

//export fib
func fib(n uint) uint {
if n < 2 {
return n
}

return fib(n-1) + fib(n-2)
}

func main() {}


go build コマンドで so ファイルを生成しましょう。

go build -buildmode=c-shared -o fib.so fib.go


PHP から呼び出す

PHP でフィボナッチ数列を再帰関数で定義してみましょう。PHP 7.0 から引数と戻り値に int の型を宣言できるようになりました。


fib.php

function fib(int $n): int {

return $n < 2 ? $n : fib($n - 1) + fib($n - 2);
}

echo fib(10), PHP_EOL;


今度は so ファイルを読み込んで、go の関数を呼び出してみましょう。MFFI エクステンションのチュートリアルはこちらをご参照ください。


go-fib.php

use MFFI\Type;

$library = new MFFI\Library('fib.so');
$fib = $library->bind('fib', [Type::TYPE_INT], Type::TYPE_INT);

echo $fib(10), PHP_EOL;



C 言語から呼び出す

せっかくなので、C 言語からも呼び出してみましょう。


fib.c

#include <stdio.h>

#include "fib.h"

int main(void) {
printf("%llu\n", fib(10));

return 0;
}


ビルドして実行してみましょう。

gcc -pthread fib.c fib.so -o fib

./fib


簡易ベンチマーク

n を10ごと増やしてベンチマークをとってみました。n = 20 まではほとんど代わらず、n = 40 で急激に大きな速度の差が生まれるようになりました。


n = 10

time php fib.php

55

real 0m0.054s
user 0m0.037s
sys 0m0.012s

time php go-fib.php

55

real 0m0.060s
user 0m0.038s
sys 0m0.017s


n = 20

time php fib.php

6765

real 0m0.060s
user 0m0.042s
sys 0m0.013s

time php go-fib.php

6765

real 0m0.059s
user 0m0.036s
sys 0m0.017s


n = 30

time php fib.php

832040

real 0m0.365s
user 0m0.346s
sys 0m0.013s

time php go-fib.php

832040

real 0m0.066s
user 0m0.045s
sys 0m0.016s


n = 40

time php fib.php

102334155

real 0m39.840s
user 0m39.177s
sys 0m0.145s

time php go-fib.php

102334155

real 0m1.237s
user 0m1.209s
sys 0m0.020s