Zephirで62進数10進数変換PHPエクステンションを作る
最初に
Phalcon 2.0でも採用されているZephirを使うと、PHPエクステンションが(比較的)簡単にできる。しかもコンパイル済みなのでとっても速い。ということで、試しに62進数10進数を作ってみた。
環境はCentOS7のインストール直後です。
Zephirインストールの前準備
bash
# yum install gcc automake autoconf libtool php-devel
# yum install http://pkgs.repoforge.org/re2c/re2c-0.13.5-1.el6.rf.x86_64.rpm
# yum install gcc automake autoconf libtool php-devel
# yum install http://pkgs.repoforge.org/re2c/re2c-0.13.5-1.el6.rf.x86_64.rpm
※ re2cは最新版だと他パッケージとの依存関係で面倒なので、上記バージョン
を入れる。他のリポジトリを使っていて、そっちにre2cがあればyumで入れてもOK。
インストール
bash
# cd /usr/local/src
# git clone https://github.com/phalcon/zephir
# git clone https://github.com/phalcon/json-c zephir/json-c
# cd zephir
# ./install-json
# ./install -c
# zephir version
0.5.9a
# php -v
PHP 5.4.16 (cli) (built: Oct 31 2014 12:59:36)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
コードを書く
bash
# cd
# zephir init orenokaisha
# cd orenokaisha
# vi orenokaisha/utils.zep
# cd /usr/local/src
# git clone https://github.com/phalcon/zephir
# git clone https://github.com/phalcon/json-c zephir/json-c
# cd zephir
# ./install-json
# ./install -c
# zephir version
0.5.9a
# php -v
PHP 5.4.16 (cli) (built: Oct 31 2014 12:59:36)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
# cd
# zephir init orenokaisha
# cd orenokaisha
# vi orenokaisha/utils.zep
zephirのソースはこちら。拡張子がzepですね。
namespace Orenokaisha;
class Utils
{
const HASH_TABLE = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static function b10to62(long value) -> string
{
string result = "0";
if (value > 0) {
long i; string hashtable, ch = "";
let hashtable = self::HASH_TABLE;
let result = "";
while(value > 0) {
let i = value % 62;
let ch = hashtable[i];
let result = ch . result;
let value = (value - i) / 62;
}
}
return result;
}
public static function b62to10(string value) -> long
{
string hashtable; long result = 0, len; int i;
let hashtable = self::HASH_TABLE;
let len = value->length() - 1;
for i in reverse range(0, len) {
let result += pow(62, len - i) * hashtable->index(chr(value[i]));
}
return result;
}
}
※ ちなみに0以下の数値が入ってきた場合は、全て0で返してますので、ご注意を。
buildとエクステンションの登録と確認
bash
# zephir build
# echo 'extension=orenokaisha.so' > /etc/php.d/orenokaisha.ini
# php -i|grep 'orenokaisha'
# zephir build
# echo 'extension=orenokaisha.so' > /etc/php.d/orenokaisha.ini
# php -i|grep 'orenokaisha'
※ php.iniのtimezoneは設定しておくべし
比較実験のコード
ではどのくらい速いのか比較して実験してみましょう♪ 100万回ループで、最後にどんだけ速いかの倍率がでます。
<?php
class Utils
{
const HASH_TABLE = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static function b10to62($value)
{
$result = "0";
if ($value > 0) {
$hashtable = self::HASH_TABLE;
$result = "";
while($value > 0) {
$i = $value % 62;
$ch = $hashtable[$i];
$result = $ch . $result;
$value = ($value - $i) / 62;
}
}
return $result;
}
public static function b62to10($s)
{
$result = 0;
$hashtable = self::HASH_TABLE;
$len = strlen($s);
for ($i = 0; $i < strlen($s); $i++) {
$result += pow(62, $len - 1 - $i) * strpos($hashtable, ($s[$i]));
}
return $result;
}
}
function test1($value)
{
$b62 = Orenokaisha\Utils::b10to62($value);
$b10 = Orenokaisha\Utils::b62to10($b62);
return ($b10 === $value);
}
function test2($value)
{
$b62 = Utils::b10to62($value);
$b10 = Utils::b62to10($b62);
return ($b10 === $value);
}
$count = 10000 * 100;
$ok1 = 0;
$err1 = 0;
$time1 = microtime(true);
for ($i = 0; $i < $count; $i++) {
if (test1($i)) {
$ok1++;
} else {
$err1++;
}
}
$lap1 = microtime(true) - $time1;
$ok2 = 0;
$err2 = 0;
$time2 = microtime(true);
for ($i = 0; $i < $count; $i++) {
if (test2($i)) {
$ok2++;
} else {
$err2++;
}
}
$lap2 = microtime(true) - $time2;
echo "test1: $ok1, $err1 => $lap1\n";
echo "test2: $ok2, $err2 => $lap2\n";
echo $lap2 / $lap1 . "\n";
結果
php
# php test.php
test1: 1000000, 0 => 2.6385660171509
test2: 1000000, 0 => 3.9418640136719
1.4939417805162
# php test.php
test1: 1000000, 0 => 2.6385660171509
test2: 1000000, 0 => 3.9418640136719
1.4939417805162
結果は、どどーんと1.49倍!!(処理時間は環境によるので、相対値のみ気にしてください)
って、あれあれあれー、これだけ?
10倍とか100倍とか速いのを期待していたわけですが、そもそもあまり複雑な処理ではなくて元から結構速いということもあり、そんなもんみたいです。
苦労の割にちょっぴり残念な結果ですが、requireの数が減るという特典もありますしね、、、。
Author And Source
この問題について(Zephirで62進数10進数変換PHPエクステンションを作る), 我々は、より多くの情報をここで見つけました https://qiita.com/kesuzuki/items/780de8fec8255220ad9f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .