「Interface」

本屋さんで興味を引いたので久しぶりに Interface という雑誌を買いました。
今回は画像処理のアルゴリズム「超解像」というやつで、低い解像度の画像を大きく引き伸ばす方法についての特集です。

中には次のような記事が載っていました。
普通画像を引き伸ばすと補間という方法を使うのが一般的ですが、補間だけで引き伸ばすと画像のぎざぎざが目立ってしまいます。今回の特集はその画像を引き伸ばすひとつの方法「超解像」というアルゴリズムについて解説です。画像のエッジを加味した補間法らしいです。

もうひとつはGPU付きのスパコンが2万5千円で買えるという話。もちろんワンボードのコンピュータではあるがUSB3、Ethernet、HDMI、SATA、イヤホンジャックが付いているというので周辺機器を買えばほぼ市販のPCと同じになるそうです。

今、新人にPCを組み立てさせる研修をしているけど、どうせだったらこんなものを使ってPCを作れといったら面白いかも知れませんね。

interface-2015-6

MVC

なんだか最近 MVC という言葉が聞かれなくなった気がする。もう浸透して語る必要がなくなったのか?それとも最近のWeb開発では向かなくなったのか?Model(データ) と View(見てくれ) と Control (制御) のコードを分けろということなのだろうが、言うはやさしくても、実際に実践しようとすると難しい。

画面を伴ったアプリケーションを作る際、データと表示の内容は当然ながら密接につながっているわけだが、プログラマから見て、データを変更する部分ではそのデータがどのように表示されているかはあまり考えなくてよいし、画面を作る側からはいつ自分が扱うデータ
以外については関心を持たなくてよいというように意識したコードが望ましいというわけだ。

最近VC++でMFCを使って書かれたコードを見ているが、若手が書いたコード(今からほぼ10年前のコードなので、今はみんな中堅なんだが)はMVCの基本を抑えていないものがほとんどだ。
たとえば ダイアログの「OK」ボタンのイベントの中で実際に目的とする処理が長々と書いてあったりする。処理時間が長いものをそのようにコーディングするのはご法度なんだが、それを正しい形でやろうとするとそこからとたんにハードルがあがってしまう。たぶん別に実行スレッドなるものを起こし、メインのスレッドとやりとりをしながら実行スレッドが終了するのを監視するようにするのが普通かと思われるが、では実行中にユーザになにか問い合わせて判断を仰ぐ必要があればとうする?とかを考えるとどんどん処理が複雑になっていってしまう。

この大変さはたとえ言語が変わっても変わらないので、UIを伴うコードを書いている人たちにとっては普遍の法則かもしれない。

ちなみに MVC を実現しようとすると一番 MFC が難しいような気がする。 MFC では最初に画面を作る際、ウイザードを使ってアプリケーションのフレームを作ることが出来るが、それがほとんど役にたったためしがない。MVC の概念がしっかりと学べるのは Java の Swing や SWT であると自分は思っているが、なにせマイナーなものなのでコードを見る機会は少ないかもしれない。

PostgreSQL のパフォーマンスチューンではまった

データベースに PostgreSQL を使った業務が運用開始になり、ちらほら障害らしき問い合わせが来る。今までに来た問い合わせで一番致命的だったのが問い合わせのパフォーマンスが悪いというもの。以前 Oracle で同じアプリケーションを動かしたときには数分で応答が返ってきたのに PostgreSQLに載せ代えたら2時間たっても終わらないとのこと。

原因を調べてみると2つのテーブルをJOINしているクエリにやたらと時間がかかっている。
一部のSQLを抜き出し、PgAdminIII で実行してみるとJOINしているキーはプライマリキーで結果も1~2件しか返ってこないはずなのに9秒もかかっている。 Explain で見てもおかしく見えない。テーブルスキャンは使われていないのになんでこう時間がかかるのかわからず2日も費やしてしまった。
クエリプラン

インターネットで調べても、SQLを書き換えてテーブルスキャンを避け、インデックスを使うようにする方法はヒットするが、完璧に見えるPlanが遅いという事象はほぼないに等しかった。

いろいろ情報をあさりまくって、最終的にカタログの pg_statio_user_tables というビューでどのようにデータブロックがアクセスされているか調べることにした。そこでわかったのは、インデックスでアクセスされているはずのテーブルの heap_blks_read, heap_blks_hit などの数値がクエリ後でぐんとあがる。これはおかしい。

以前別なDBMSでパフォーマンスチューンでテーブルごとに統計を取る必要があったことを思い出しそれを実行してみるとクエリ所要時間が9秒から11msまで落ちた。

前の場合はプランが統計を採る前と後ではまるで変わったので、今回は統計を採る必要がないと判断したのが間違いだった。 PgAdminIII で表示される統計は実際の動作と違う場合があることがわかった。

今日は、全テーブルに一括して統計を採るスクリプトを書かないと…

PostgreSQL が面白い

ここ数年、業務で PostgreSQL を使用している。アプリケーションのDBMSとして使うのはもちろんだが、最近はデータベースそのものの構築を自動化することを行っている。

データベースの内部を触ることが多いので、テーブルの構造を持っているテーブル(カタログ)を調べて、テーブルが存在しているかどうかをチェックする機能を作ったりしているが、その中で PostgreSQL 固有の機能で面白い機能を発見した。

PostgreSQL ではほかのDBMSと同じようにスキーマという単位でテーブル等を管理している。スキーマが違えば同じ名前のテーブルが存在することが出来る。テーブルをアクセスする際、スキーマ名で修飾しないでテーブルをアクセスすると、セッションの search_path という変数で羅列したスキーマの順でアクセスするテーブルを検索する。

テーブルが存在するかどうかを調べるためにはこのsearch_path のせいで複雑なSQLを組まないといけないと思っていたのだが、最近発見したある機能で、テーブルの存在チェックを簡単に出来ることがわかった。

その機能とはテーブル名の文字列を regclass というタイプでキャストするということ。たとえばtable_a というテーブルがDB内に存在ししかもアクセス可能かどうかを調べるためには次のようなSQLを使用する。

select 'table_a'::regclass

こうするだけで結果としてそのテーブルの OID が返ってくる。もし存在しなければエラーとなる。(OIDが返ってくるのだが実際にpsql や PgAdminIII でクエリ結果として表示されるのはテーブル名そのものになっている)

これを応用して、どのスキーマのテーブルが実際にアクセスされているかどうかを調べるSQLは

select nspname from pg_namespace n, pg_class c
where n.oid = c.relnamespace and c.oid ='table_a'::regclass::oid

あとはこのSQLを組み込み、テーブルが存在しなかったときのためにエラー処理を入れればよい。

PostgreSQL ではキャストも独自で定義できるようだ。なるほどこういう使い方も出来るのかと目からうろこの瞬間であった。