hiphop-php試してみた

facebookが開発したhiphop-php試してみた。

これが何かってのは下記参照。

http://blog.candycane.jp/archives/275

wiki
https://github.com/facebook/hiphop-php/wiki

インスコは結構時間かかります。あと入れないといけないライブラリ大杉。

OSはubuntu10.10で/usr/local/hiphop-phpにインストールした。

サンプルコード

<?php
function is_prime($n) {
    if ($n < 2) {
        return false;
    } else if ($n == 2) {
        return true;
    } else if ($n % 2 == 0) {
        return false;
    }
    $i = 3;
    while ($i * $i <= $n) {
        if ($n % $i == 0) {
            return false;
        }
        $i += 2;
    }
    return true;
}

function main() {
    $ans = 0;
    for ($i=0; $i<=2000000; ++$i) {
        if (is_prime($i)) {
            $ans += $i;
        }
    }
    echo $ans . "\n";
}
$start = microtime(true);
main();
$ttfb = microtime(true) - $start;

echo "----------------------------\n";
echo "exec time $ttfb \n";
echo "end.\n";

phpとhphpiで実行して比較してみた。

php


$ /usr/local/php/bin/php euler10.php
142913828922

                                                      • -

exec time 12.92103099823
end.

PHP遅い・・・

hiphop-php

hphpi


$ /usr/local/hiphop-php/src/hphpi/hphpi -f euler10.php
142913828922

                                                      • -

exec time 40.044190883636
end.

えっ

どういうことなの・・・

ペチパーの希望は消えてしまったのか


[2011-02-23追記]

一度コンパイルしてから実行したらphp-cliで実行したときの3倍くらいの速度になりました。


$ /usr/local/hiphop-php/src/hphp/hphp euler10.php --keep-tempdir=1 --log=3
running hphp...
creating temporary directory /tmp/hphp_Lo6ArD ...
parsing inputs...
parsing inputs took 0'00" (6 ms) wall time
pre-optimizing...
pre-optimizing took 0'00" (0 ms) wall time
inferring types...
inferring types took 0'00" (0 ms) wall time
post-optimizing...
post-optimizing took 0'00" (0 ms) wall time
creating CPP files...
creating CPP files took 0'00" (64 ms) wall time
compiling and linking CPP files...

compiling and linking CPP files took 1'18" (78558 ms) wall time
running executable /tmp/hphp_Lo6ArD/program --file euler10.php...
142913828922

                                                      • -

exec time 4.4274728298187
end.
all files saved in /tmp/hphp_Lo6ArD ...
running hphp took 1'23" (83332 ms) wall time

実行してみる


$ /tmp/hphp_Lo6ArD/program --file euler10.php
142913828922

                                                      • -

exec time 4.4373819828033
end.

おおおおお!!

これでペチパーは救われた。

FizzBuzzで30byteすかぁ

でけた。


$ vi fizzbuzz.fb
FizzBuzFizzBuzFizzBuzFizzBuzF

で実行。


$ ./fb.py < fizzbuzz.txt
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
31
32
Fizz
34
Buzz
Fizz
37
38
Fizz
Buzz
41
Fizz
43
44
FizzBuzz
46
47
Fizz
49
Buzz
Fizz
52
53
Fizz
Buzz
56
Fizz
58
59
FizzBuzz
61
62
Fizz
64
Buzz
Fizz
67
68
Fizz
Buzz
71
Fizz
73
74
FizzBuzz
76
77
Fizz
79
Buzz
Fizz
82
83
Fizz
Buzz
86
Fizz
88
89
FizzBuzz
91
92
Fizz
94
Buzz
Fizz
97
98
Fizz
Buzz

fb.pyの中身。

#!/usr/bin/env python
import sys
if __name__ == "__main__":
    line = sys.stdin.readline()
    l = len(line)
    if l != 30:
        sys.exit(-1)
    print "".join(((i%3==0)*'Fizz'+(i%5==0)*'Buzz' or str(i))+"\n"for i in range(1,101)),

何でもいいから30byte渡すとFizzBuzzやってくれます。

はい、終了。

RedmineのGitのリポジトリブラウザで改行を無視して差分表示

2011年一発目。

Redmine + Gitで運用してるケースの話。

RedmineからGitのリポジトリを参照してる場合に画面からリビジョンのdiffが見れる。

ただこのままだと改行コードが変更された場合(例えばdos->unix)に全行ハイライト表示されて改修箇所の視認がしづらい。

改行コードの変更がプロジェクトに与える影響が無視出来るレベルなら表示させないでいいと思う。

下記のコードを修正して改行の無視を指定出来た。

./lib/redmine/scm/adapters/git_adapter.rb

line 223付近のshowに-wを追加。

cmd = "#{GIT_BIN} --git-dir #{target('')} show -w #{shell_quote identifier_from}" if
cmd = "#{GIT_BIN} --git-dir #{target('')} diff #{shell_quote identifier_to} #{shell_quote identifier_from}" if !identifier_to.nil?

で、サーバを再起動して改行が無視される事を確認。



[20120125]追記

redmine-1.3.0へアップデートしたらコード変わってた。
lib/redmine/scm/adapters/git_adapter.rb
下記の様に修正。

        def diff(path, identifier_from, identifier_to=nil)
          path ||= ''
          cmd_args = []
          if identifier_to
            cmd_args << "diff" << "--no-color" << "-w" <<  identifier_to << identifier_from
          else
            cmd_args << "show" << "--no-color" << "-w" << identifier_from
          end
          cmd_args << "--" <<  scm_iconv(@path_encoding, 'UTF-8', path) unless path.empty?
          diff = []
          scm_cmd *cmd_args do |io|
            io.each_line do |line|
              diff << line
            end
          end
          diff
        rescue ScmCommandAborted
          nil
        end

apache2.3メモ

httpd-2.3.8.tar.gzを手動で入れたんだけど


client denied by server configuration:
こんなログ吐いて動いてくれない。

原因はこれ


<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied <- これ
</Directory>

下記の修正で動いてくれた


Require all granted

とりあえず開発はこれで。

でもこれ問題あるかも知れないので要調査。

HBaseへPHPから繋いでみた

HBaseへThriftを利用してPHPからアクセスするサンプル。

$GLOBALS['THRIFT_ROOT'] = '/usr/share/php/Thrift';

require_once $GLOBALS['THRIFT_ROOT'].'/Thrift.php';
require_once $GLOBALS['THRIFT_ROOT'].'/transport/TSocket.php';
require_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php';
require_once $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php';
require_once $GLOBALS['THRIFT_ROOT'].'/packages/Hbase/Hbase.php';

try {
    $socket = new TSocket('localhost', 9090);
    $socket->setSendTimeout(1000); // One seconds (too long for production, but this is just a demo ;)
    $socket->setRecvTimeout(2000); // Twe seconds
    $transport = new TBufferedTransport($socket);
    $transport->open();
    $protocol = new TBinaryProtocolAccelerated($transport);
    $client   = new HbaseClient($protocol);

    $tablename = "test";

    //var_dump($client->getColumnDescriptors($tablename));
    //var_dump($client->getTableRegions($tablename));
    //var_dump($client->getRowWithColumns('counter','rows','rows'));
    $c = $client->getRowWithColumns('counter','rows','rows');
    $cnt = (int)$c[0]->columns['rows:']->value + 1;
    $client->mutateRow('counter', 'rows', array(new Mutation(array('column'=>'rows','value'=>$cnt))));
    $row = date("YmdH:") . str_pad($cnt, 10, "0", STR_PAD_LEFT);

    $mutations = array(
        new Mutation(
            array('column'=>'userid', 'value'=>$userid,)),
        new Mutation(
            array('column'=>'passwd', 'value'=>$passwd,)),
        new Mutation(
            array('column'=>'name', 'value'=>$name,)),
        new Mutation(
            array('column'=>'status', 'value'=>$status,)),
        new Mutation(
            array('column'=>'lastaccess', 'value'=>date("YmdHis"),)),
        );
    //print_r($mutations);
    $client->mutateRow($tablename, $row, $mutations);


} catch (TException $e) {
    echo "/* TException\n";
    echo $e->getMessage()."\n";
    echo "*/\n";
} catch (Exception $e) {
    echo "/*\n";
    echo $e->getMessage()."\n";
    echo "*/\n";
}
$transport->close();

変数とかカラム名とかは適当。

mutateRowメソッドでデータの書き込みをしている。

$rowはRDBMSで言うPRIMARYKEY。

第3引数にMutationクラスを利用しないといけない。

この処理だけで100msほどかかったので高負荷のフロントには向かない。

もう少し情報まとめたらまた書く。

redmineのメニューを追加

redmineのヘッダのメインメニューに項目を追加する。

追加するのは「ガントチャート」と「カレンダー」

修正したのは以下のファイル。

[app/controllers/issues_controller.rb]

class IssuesController < ApplicationController
  menu_item :new_issue, :only => :new
  menu_item :gantt_issue, :only => :gantt           # <- 追記
  menu_item :calendar_issue, :only => :calendar     # <- 追記
  .
  .
  .

[lib/redmine.rb]
こっちは3行

Redmine::MenuManager.map :project_menu do |menu|
  .
  .
  menu.push :new_issue, { :controller => 'issues', :action => 'new' }, :param => :project_id, :caption => :label_issue_new
  menu.push :gantt_issue,     { :controller => 'issues', :action => 'gantt' },    :param => :project_id, :caption => :label_gantt
  menu.push :calendar_issue,  { :controller => 'issues', :action => 'calendar' }, :param => :project_id, :caption => :label_calendar,
  .
  .
  .
end


[参考URL]
http://chocoapricot.cocolog-nifty.com/blog/2008/07/redmine_1316.html


@hibariyaありがとう。