ハードディスクがギリギリになったのは、ちょっと理由があって、
2ちゃんねる(N.T.Technology)の有料サービス● のお試し版が株式会社ゼロ運営のゲーム
ニダークエスト2で貰えたため、それを使って過去ログを集めてました。
ざっと、現在までにニュース速報VIPやPCゲーム板など数十万スレッドが収集でき、
当分、読む物には困りそうもありません。
# 前にもこんな事書いた気がする。
file_edit
これが勉強がてらC言語で書いたディレクトリリストと datファイルの先頭4文字を判断するプログラム。
CodeGearのサイトにあったリファレンスを見つつ作ってみたんだけども、意外と簡単に動くものです。
こうやって少しづつ作っていくことで、段々と作れる物が増えて行ければいいなぁ。
PHPは、関数が豊富なのと、実用的というか、直ぐ使えるような関数が一杯なので、
それと較べると、C言語は結構しんどいです。
「PHPポケットリファレンス」みたいな本がC言語にも有ればいいのになぁ。
「プログラミング言語C」の第2版は読んでみましたが、結構大変。
構造体とかが使えるようになれば、また一段と作れる物が増えるんだろうなぁ。
用途が用途だけに行数をカウントする処理を結構書いたりするのですが、
今まで file 関数で配列に入れて count 関数で取得という方法を主に使っていたんですよね。
最近になって、クローラーの改良時に実は foepn も結構早いんじゃね?
ファイルアクセスも減るんじゃね?という感じでベンチマークを取ってみました。
まずは、 file 関数を使った例。count も sizeof もエイリアスなので、どちらでもOK。
$buf = file(“hogehoge.dat”); //1001行のファイル
$count1 = count($buf);
unset($buf);
これは、1000回ループで 4.653011 秒という結果になりました。
一方 fopen を使ってカウントする例。
$fp = fopen(“hogehoge.dat”, “r”); //1001行のファイル
for ($count2=0;!feof($fp),fgets($fp);$count2++);
fclose($fp);
こちらは、 3.800635 秒とコンマ7程度早くなりました。
しかし、結局1000回実行してやっとコンマ7という結果でした。
早いには変わりないと思いますが…、まぁこんなもんなのかなぁ。
ファイルの中身を配列として読み込む file という便利関数があるんですが、
これにはちょっと使い時があります。
PHP には memory_limit という設定があり、この設定値を超えると
処理が出来ないため、エラーになってしまいます。
実は file 関数とこの設定値は結構リンクしていて、memory_limit をバケツに例えると
バケツに対してバケツの容量以下の水を扱うには良いのですが、
バケツに対して、25mプール一杯の水を注ごうとするとあふれてしまうのと同じように下記のエラーになってしまいます。
Allowed memory size of xxx bytes exhausted (tried to allocate xxx bytes)
つまり、あまりにも大きいデータを読み込む時に file 関数は向いていないのです。
こういった場合、どうしたらいいのか?
答えは簡単で、 fopen でファイルを開いて fgets すれば良いだけです。
fopen はファイルポインタですから、使用した時点ではファイルの内容は読み込みません。
fgets を使用してはじめて読み込むわけですが、 fgets は指定バイト数もしくはEOFまでの読み込みであり、
巨大なデータでも行端で切り刻んで読み込むことが出来るため、前述のようなエラーにはならなかったりします。
file_get_contents も file と同じようなものと考えて組んでいかないと変なところでエラーが出てしまうので、
使い所には注意するべきですね。
あと、 PHP は一度スカラー変数として定義したものは、スカラー変数としてしか使えないので、
<?
$hoge = 1234;
$hoge[0] = 5678;
?>
というようなものを書くと Cannot use a scalar value as an array というエラーになりますよん。
cURL関数の説明をちょっと読んだら面白そうだったので、クローラーの取得部分を並列化してみました。
これで、単線だったローカル線がいきなり、複々線化してさらに高架も建設したような感じに成長。
気になる取得数は3000スレ/hourをもうすぐ超えるのではないかというほど。
同時処理数をあんまり多くするとセッションがドンドン食われるので、
その辺りは負荷と兼ね合うようHTTPの標準的な数値に調整。
これでクローラーのメジャーバージョンはv6になった。
# Blu-ray マイスター検定クイズでも95%を超えたので、
# マイスター認定証が貰えるらしい。 現在109人中 16位だそうで。
やっぱり、頭がボーっとしている時に作業してはダメですね。
一昨日、クローラーの更新をしてそのまま1時間普通に動いていたので、
大丈夫そうかなとか思っていたんですけど、甘かったです。
さっき見たら、システムのリソースがuserに滅茶苦茶取られていて、
機能変更したプログラムを見直したら本来ループカウントに使うべきでない変数を
ループカウントに使って、無限ループに陥ってました。
シャッキリ大切。
# Blu-ray マイスターになりますた。
Windowsでは、Shift_JISによく似たCP932(MS932)という文字コードが用いられているわけですが、
CP932には存在している文字、記号がShift_JISには存在しない場合「?」に置き換えられて入力されます。
実は、過去ログ検索を作っているときに最初Shift_JISでテーブルを作っていたのですが、
これの影響で文字化けが起きていることが後で解りました。
CP932の文字をMySQLのテーブルに挿入する方法の一つに
テーブルの照会順序をutf8_unicode_ciに変えることがあり、
CP932に存在して、Shift_JISには存在しない文字、記号が扱えるようになります。
つまり、文字が存在しないならば、文字が存在する文字コードを使えば良いと言うことです。
すべてShift_JISのテーブルに以下のようなSQL文を実行すると盛大に文字化けしてしまうわけですが、
INSERT INTO `hogehoge` VALUES(“1″, “Right Triangle”, “⊿”);
CP932を扱う列をUTF8にして、以下のように書き直すことで文字化けを防ぐことが出来ます。
INSERT INTO `hogehoge` VALUES(“1″, “Right Triangle”, CONVERT(_cp932 “⊿” USING utf8));
まぁ、最初からUTF8にすれば良いってだけの話です。
readc.cgiは描画関係はだいたい終わった。
コード自体はみやすくなったものの、最短時間は現行より速くない気がする。
ただ、平均時間は明らかに速くなっていて、殆ど0.3秒以内に処理が終わる。
今のコードの行数は840行。
どうにかして高速化出来ないかなぁ?
一昨日書いたToDoはこんな感じだったんだけど、概ね消化することができた。
- 巡回スレッド数の設定 → 実装完了
- 取得する最低レス数の設定 → 設定部分は終了あとは実装だけ
- 定期実行 → 実装完了
作業を進めるに当たって、一つ問題があって、DOSプロンプトを消すことが出来ない状態。
つまり、ふたばブラウザの双助だったり、ニコニコ動画のローカルプロクシNicoCacheみたいな状況。
どうにかこれを打開できないか考えてみたのだけれど、WinBinderを使うとGUIウィンドウがハングするし
タスクトレイに入れられるらしいPHP-GTK2は、PHP5で動かない。
PHP CompilerというPHP5に対応したコンパイラも有るんだけれど、これはPHP-GTKのエラーが出て動かない。
うーん、どうしたものか。
ユーザー側でタスクトレイに入れるソフトを使うという手も有るけど…。
もうちょっと情報を集めてみよう。
XREAで使っている一部のデータベーステーブルをMySQLからSQLiteに置き換えた。
何回やってもCGIとして動かしているスクリプトからレコードの追加が出来なかったんだけど、
よく見たらファイルのパーミッションが書き込み出来ないようになっていたりと、ちょっと変なところで詰まったけど、
記述部分自体はMySQLのベタ書きから、PDOを使う形式に数行書き換えるだけだから、結構簡単だった。
(最近は、たまにMDB2を使ってるけど、前は全くそういった類のものは一切使ってなかった。)
この部分のSQLite化により、過去ログ倉庫にdatを転送するとき等に使う
データベースのアクセス速度がちょっと速くなったんじゃないかと思う。
もともと、後から書き込んでも内容が重複しないファイルとしてDBMSを使っているだけだから
それほど高度な内容を扱っている部分でもないし、SQLiteで十分。
なんとなくC++をさわってみたんだけれども、よくわからない。
そもそも、C++なんて今まで触ったこともない。
こんなんで良いのかホントに…。
ネットの情報のみでやるにはきっついなぁ。