カテゴリー「書籍・雑誌」の32件の記事

2015/07/11

[読書]Getting Started with Hazelcast

第2版出版(されることを私が知った)記念に。 Kindle版は2015/08/05に入手できるようです。

 

 

Hazelcastとは、分散キャッシュ(Distibuted Cache)だとかインメモリデータグリッド(In-Memory Data Grid; IMDG)だとか呼ばれているカテゴリの製品です。
んじゃあ分散キャッシュ/IMDGとは何ぞやということなんですが、それについてはOracle Coherenceについての資料を読むと十分理解できるかと思います。
日本語ドキュメントも充実していますので、いきなりHazelcast関連ドキュメントから入るよりとっつきやすいかと。
今サクッとググってみた結果を以下に載せますが、他にも色々検索で得られると思います。

これらを流し読みした後、Mastering Hazelcast を読めばHazelcastがどんなものかはわかるかと思います。

IMDGプロダクトの性質は、RDBMSに近い感じでしょうか。どういうことかというと、

  • お試しで使ってみたり、自身のアプリケーションに組み込むことについてはさほど大変ではない
  • 性能を上げるための実装方法や、運用(障害対応など)にはノウハウがいる

みたいな。

 

さて本題の、読書感想ですが、読んだ当時(2014年末ごろ?)に書いていたものがありました。

この本で解説されているHazelcastのバージョンは2.6ですが、このレビューを記載した時点での最新リリースバージョンは3.4です。
変更されているAPIも多くあり、サンプルコードを動かすためのマイグレーションにも労力が必要です。

それに加えて、記載内容も基礎の基礎に留まっており薄いです。
出版当時の状況はわかりませんが、現在に至っては、公式サイトのドキュメント、及び公式サイト内にあるオンラインブック Mastering Hazelcast を読めば、この本以上の情報が得られます。

というわけで、今から第1版を購入するのはおすすめしません。

そもそも前述の通り、導入自体はさほど大変ではないので、その部分については無料で入手できる範囲の資料で事足りる気がします。

v2.6とv3.4をの差異を当時記録したものがありますので、万が一本書を読むようなら参考にしてみてください。

2011/07/23

[読書]Hello, world!からはじめるCUDAプログラミング - CUDA by Example 汎用GPUプログラミング入門

CUDAプログラミング入門用に2冊購入しました。

 

「はじめてのCUDAプログラミング」の著者は東工大のGPUコンピューティング研究会の主査/幹事をされてたりする、GPGPU研究の第一人者の方たち、だそうです。

本書は日本語の書籍としては早い時期に出版され、web上で見ると当時の評判もかなり良いようです。ただ、出版された時期が早い分、今から読むと、現在のアーキテクチャ(compute capability 2.x(Fermi))やCUDA4.0のプログラミングモデルとは異なってしまっている部分があります。

また、GPU上での速度最適化を念頭に説明が進められていきますので、取り敢えずGPU上でプログラム動かしてみたいんだ!と考えているとちょっとじれったいです(GPU上で計算しようとする動機は実行速度を上げることであるのが普通なので、このアプローチが変なわけではないです)。

 

一方で「CUDA BY EXAMPLE」の方は、本当にハローワールドから始まります。普通のCプログラムを作る –> GPU上で動作するように変更する –> それを最適化する という順番で進めていきますので、手を動かしプログラムを動かしながら理解できます。ですのでまずプログラム動かしたいと考えている私のような人にはこちらの方がお勧めです。(ちなみに結構初っ端に出てくるプログラム(julia_gpu.cu)がコンパイルエラーになって焦ったりしますがこちらに対応方法が書いてありました。)

ちなみにこちらはcompute capability2.0以降ですが、CUDA4.0よりは前に出版されています。CUDA3.xとCUDA4.0で変わった部分についての言及は無かったように思います(が、言い切れるほどの知識はまだ無いです)。

 

いずれの本を読み終えたとしても、CUDA C Programming Guide(CUDA Toolkitをインストールしていればローカルにもあると思います)に書かれている内容の一部しかカバーできていないので、次はこのGuideを読むことになると思います。(はてなダイアリでid:nobnakさんが過去のバージョン和訳されていらっしゃるのを見つけましたが、現在の最新バージョンであるCUDA4.0とは異なる部分もあるようです。)

 

ついでに書いておくと、昨日NVIDIA GTC Workshop Japan 2011というのがあったそうで、飯塚拓郎さんがセッションで用いたソース(PDF資料)が4.0でのC++サンプルとして良さそうなので後日参照させてもらおうと考えています。

2011/07/19

[読書]誰を対象にした内容なのか不明確 “Java: The Good Parts”

立ち読みで済ませてしまった本です。

著者のJim Waldoさんという方はJava設計にも大きく貢献された方…だそうですが(確か著者紹介のところに書いてあったかな?)、本書の内容はその経歴が生かされていないと感じました。

タイトルからしてn匹目のドジョウ感がありますし、目次をみても、普通にJavaを学んでいく上で得られるような知識ばかりですし、他の言語から移ってきた人にとっても、大抵の機能は過去学んだ言語にもあることでしょう。敢えて言うとC以前の言語を学んで、さあ次はJavaだ!というような人にとっては有用でしょうか…?それにしては出版された時代が遅すぎるような気もしますが。

「Javaには他の言語と違ってこんな便利な機能が」「他の言語のやり方とは違ってJavaだとこうするのが良い」みたいなことが書かれていることを期待させるタイトルですが、もしタイトルを見てそのように感じたのであれば立ち読みしてみてから購入を検討することをおすすめします。

2011/05/05

[読書]プログラマが知るべき97のこと その1 『19:誰にとっての「利便性」か』

 

本書プログラマが知るべき97のことを読み進めているといくつか過去の経験から言いたいことが出てきたので、これはメモ取りながら読んだ方が良いな、と思っていたのですが、そんな環境で本を読む時間がほとんどないことに気付きました(普段読書するのは吊革につかまりながら、なのです)。

また、途中まで書いたメモを読み返すと、結構背景補足を行わないといけないことに気付き、これは私がこの本のようにエッセイを書くのと変わらないな、と挫折しました。

そんなわけで「その1」と銘打ってはいますが(いつもの通り)続編があるかどうかは分かりません…

ちなみに、本書に収録されているエッセイは、CC-by-3.0-USによってライセンスされているそうで、オライリーのサイトで原文を閲覧できます(日本語版では日本の方が書かれた10本のエッセイが追加収録されていますので、本書の全てのエッセイが、というはけではないです)。日本語訳については一部のようですがWikisourceで読めます

 

本章『誰にとっての「利便性」か』では、作る側の利便性よりも使う側の利便性を考えてAPIを設計しましょう、という内容が書かれています。詳細は他の方がすでに書かれていますのでそちらを参照するのが良いでしょう。

そして、以下のような具体例が挙がっています。

たとえば、 walk(true) というようなコードを書かされるよりは、単に run と書ける方が間違いなく使いやすいでしょう。walkとrunは本質的には同じ動作で、ただスピードが違うだけとみなすこともできるのですが、言葉が2つある方が使う側にとっては便利なのです。

私は、著者の主張『作る側の利便性よりも使う側の利便性を考えてAPIを設計しましょう』というのには賛成ですが、walkとrunの例には賛同できません。ただスピードが違うだけなのであれば、ただスピードが違うだけなのだと使用者に伝えるべきで、それを最も明示できる方法の一つがメソッドシグニチャによる表明だと考えます。

今回の例ではwalkとrunの2種しか登場ませんが、これより種類が多い、あるいは種類が多くなる可能性があることを考えてみましょう。おそらく日本の列車種別のように特急、準急、快速ってあるけど結局どれが速いの?ということになるでしょうし、動く(walk/run)以外のAPIも同じように並んでいるとメソッド名を見ただけでは判断がつかなくなると思います。これは使う側の利便性も低下していることになるでしょう。

この例で、私が採ると思われる策は、速さをenumの引数で表すことです。つまり move(Speed speed) のような形になります(Speedがenum)。

  • runとwalkという文字列で表したいのであれば、そのようにSpeedを定義すれば良い。
  • 速さの種類が増えてもインタフェースの互換性は失われない。また、前述の列車種別のような例でもenumの定義順から速さの順番は推測できる。
  • Javaではenumでストラテジパターンも実現可能であり、設計に幅ができる。

(JavaのEnum詳細については書籍Effective Java 第2版 「項目30 int定数の代わりにenumを使用する」を参照してみてください。)

…もしかすると、著者と私で想定している背景が異なっているため、上のような結論の差異が出ているのかもしれません。実際に設計する際には「あの本に載っていたから」を理由にするのではなく、前提条件がその本と一致しているか、自分の問題にも適用するのが最適なのか、などといったことも考慮する必要がある、というのを覚えておくべきでしょう。

 

最後に。本書は「(比較的著名な)プログラマ97人がが考えている、知っておくべきこと集」であって、「プログラマが知るべきことのうちBEST97」ではないことに留意しましょう。もし今年SEになったばかりの人に何か良い本は無いかと尋ねられた場合、おそらく私が本書を勧めることは無いと思います。本書が悪書である、と言いたいわけではなく、新人SEが本書より先に読むべきものは他に沢山ある、ということです(個人的には、本書はファンブックに分類されるものだと考えます)。

(補足: 便宜上プログラマ97人と書きましたが、実際には1人の方が複数のエッセイを書かれていますので正確には73人です(前述したとおり日本語版では+8名)。)

2011/02/27

[書籍]DDD日本語版『エリック・エヴァンスのドメイン駆動設計』の発売日が決定した

でも、夏になる前にぐらいに出るーぐらいに思っていただけると幸いです。 RT @kohsei: はい、今のところ、3月に刊行予定のようです! RT @afukui: DDD日本語版は来年出ます。と @kohsei さんが言ってたような。 #devlove #devlove1218
3:36 PM Dec 21st, 2010 TweetDeckから

というtweetをたまたま見つけて心待ちにしていたのですが、『エリック・エヴァンスのドメイン駆動設計』という名前で発売されるようです。2011年4月8日(amazonでは9日になってますね)、5,460円。

原著のタイトルはDomain-Driven Design: Tackling Complexity in the Heart of Software、愛称はDDDです。今の時点ではこの名前で検索かけた方が多くの情報を得られるかと思います。

ドメイン駆動型設計は、上流設計作業内容の見える化だ!!本書は、有益なソフトウェアのドメインモデルを構築するためのテクニック、ノウハウ、パターンを満載した設計ガイドブックです。たとえば、金融・証券系システムなら入出金、流通系システムなら集配、amazonなどネット通販系システムなら買い物かごなど、開発対象領域のシステム毎に必要となる機能やそれらを実現する設計パターンが抽出でき、これにより、従来は分析・設計のひと言でくくられていた作業工程の不透明部分が開発対象領域毎に明確に定義できます。本書は、これらの知見を網羅し、利用するためのポイントをまとめ、現場で分析・設計をする開発技術者必見の1冊となっています。

 

本書の要約のようなものがDomain-Driven Design Quicklyとして日本語版も無料で公開されています(要メンバー登録)。こちらで本書のイメージが掴めるのではないでしょうか。

 

さらに、Qcon Tokyo 2011セッションスピーカとして著者のEric Evans氏が来日され、翌日には来日記念チュートリアルなんかも開催されるようです(参加費ちょっと高いですが)。

QCon Tokyo 2011の開催日が本書発売直後の4月12日(火)なので、読んで予習しとけよーってことでしょう。

 

ちなみに本書、翔泳社のオンラインショップで予約するとTシャツがもらえるそうですよ…!

2011/01/03

[読書]彼女と二人で「C」体験!にあえてツッコむv2.0

 

副題は”絶頂ポリモーフィズム”。今回もストーリーにはなるべく触れないようにしていますが、終盤のギミックに関わっているのでネタバレありです。ちなみに前回はこちら

 

コンピュータ対戦プログラミングについてよくは知らないのですが、

  • プレイヤ(チーム)ごとに1つのクライアントがあって、自分のユニット(駒)に命令を出すために用いる。
  • それぞれのプレイヤの命令は1つのサーバに集められ、1ターンごとに各プレイヤの命令を集計し、結果をそれぞれのプレイヤに返す。

みたいな感じでしょうか。あと、

あたりを見ると、

  • プレイヤは命令を事前に設定された規約に従った文字列(プロトコル、あるいはもうちょっと明確にした「電文(業界用語)」と呼ぶのが適切ですかね)に変換した上でサーバに送る。

というのも共通的なものでしょうか。

上記3つのゲームでは、各プレイヤの操作するユニットは同性能ですが、本劇では基本性能もカスタマイズできるようなので、どちらかというとRobocodeみたなものをイメージするのが良さそうです。

 

さて本題です。

p.98

[前略]プログラムはワンステップずつ処理される。たった一行のコードで、すべての兵士オブジェクトに対し、そんな命令が下せるものなのか―。
この大会では、セミコロンまでの一処理を一ステップまで扱っている。たとえば、
int i;
i = 5;
これで二行。二ステップだ。

少し前(p.85)でも説明は出ていますが、ここではもう少し具体的な記述になっています。ソースコードそのものが性能に寄与するという点では、冒頭で挙げた実際のゲームいずれとも異なります。切れ負けルールのあるコンピュータ将棋なんかだと、演算性能の高いクライアントで参加する方が相対的に有利になりますが、このルールだと純粋にアルゴリズム勝負になります…かね。前後半合わせて600ターン(p.85参照)なので、かなり厳しいルールだと思います。

ここでのステップの説明はWikipediaの論理LOCにもう少し詳しく書かれています。サーバがステップを認識できるということは、クライアントからサーバに送信するデータは、冒頭に記載したような単純な命令文字列とは異なります。また、コンパイルエラーなどの場面も登場することから、劇中のC/C++は実世界同様(インタプリタ言語ではなく)コンパイラ言語ということがわかります。プレイヤプログラムはソースコードの状態でサーバへ送信し、サーバ上でデバッグ情報をつけて最適化なしでコンパイル・実行する、みたいな…?

 

p.218

同じ名前のメソッドを、他のクラスと被ってなお、いくつでも作成できる。むしろ、同じ意味を持つものなら、同じ名前を付けるべき―。
多態性(ポリモーフィズム)。
それが保証されているC++言語だからこそ、やりえた作戦だ。

なんかグローバル関数とメンバ関数の対比、ひいてはCとC++の対比のような表現になっていますがそれはともかく。

劇中では、多態性を利用して、一方のクラスインスタンスを他方のクラスインスタンスに見せかけています。

C++などの静的型付け言語(p.123参照)での多態性は、一般的には共通の基底クラスへアップキャストすることで実現します。しかし、ここでは、それぞれのクラスが共通の基底クラスを持たず、単純に同名の関数を持っているだけです。従って、これは継承による多態性の実現ではなく、ダックタイピングによる多態性の実現です。

  • C++でダックタイピングを行おうとした場合、あらかじめ型がわかっていないとコンパイルできない(リフレクションを備えている言語であればこの限りではありませんが…)。継承によって多態性を実現していたとしても、共通の基底クラスは相手チームローカルな情報であって自チームには知らされていないため、この場合も判断は不可能でしょう。
  • ダックタイピングとは、Wikipediaにあるとおり、歩かせてみて鳴かせてみて初めてアヒルとわかるものであり、行動を起こす前(劇中の表現を用いると相手が反応する前、すなわちこちらが攻撃行動をとる前)にアヒルであると判断することは不可能です。

ちなみに、戦況を映すスクリーン上では、異なるクラスのインスタンスであるユニットはそれぞれ別物であると認識できています(p.214参照)ので、サーバへは実行時型情報のようなものを通知するようになっているのかもしれません。

 

p.231

『0x335afc』
[中略]
「”デマゴゴス”の本体アドレスですっ!」
[中略]
一騎の”ヘタイロイ”が、何もないマスに向かって突撃する。[後略]

普通に考えると、アドレス、というのはフィールドの座標のことでしょうか。かなり広大なフィールドに思えますが、0番地から始まっているとは限りませんし、冒頭に示した高専プログラミングコンテスト募集要項中「フィールドのセル番号」にあるように、無効番地がある可能性もありますね。

 

p.32

“『第二十二回プログラミング甲子園』、開会式を行います―”

p.151

「あたしの意見じゃないわよ」
「誰だよ」
「坂本龍馬」

「二十二回」「坂本龍馬」というのは第21回高専プログラミングコンテストへのオマージュでしょうか。

p.118

int nAction = nGetAction();

if (nAction == OPARATION_ATTAK)

{

この定数”OPARATION_ATTAK”は大会主催者が提供しているライブラリで定義しているものでしょうか。これも同コンテスト決勝戦 procon21-08.wmv の映像13分ごろ「異常ではない」のオマージュですね(補足しておくと、実際のプロコンの方はバグだったようです(同映像42分ごろ))。他ではp.231,p.258で英字の誤字を見つけました。

 

 

One More Thing:

「彼女と二人で」の英語表現が”by she and two people”(p.4参照)になってますが、これって多態的にヤバくないでしょうか…

(追記: これはexcite翻訳(powered by BizLingo)の仕業ですね)

2010/10/21

SAMSUNG GALAXY BLOGGERS NIGHT #itmgalaxy に参加してインカメラなどを試す

今週の月曜日、10月18日にあった、SAMSUNG GALAXY BLOGGERS NIGHTに参加してGALAXY SとGALAXY Tabを(CEATECに引き続き)触ってきました。

なんと、コムギドットネットの管理者さんと同じテーブルになって少しお話しすることができました。18日の時点ですでにT-Mobile版HT-03A(T-Mobile G2、であってるかな?)にAndroid2.2を入れられていらっしゃいました…さすが。GALAXY Sのベンチマークについても少しご説明頂いたのですが、すみません、あんまり理解できませんでした(Nexus Oneは現時点でも結構すごいらしいです)。ベンチマーク結果の写真なんかも撮られていたので、そのうちblogで公開していただけるかも。

 

今回は何を試そうか、ということで、front facing camera(インカメラ)がどんな具合でプログラミングできるのか見てみました。

GALAXY Sのインカメラはハード的にはついててソフト的に機能を切ってるだけだ、みたいな都市伝説も挙がってたりしますが、インカメラをつけてないのはコスト面を考えてのことだと思うので、それは無いでしょう…ドコモのラインナップを考えたうえで、GALAXY Sはシンプル低価格な普及機種という位置づけにしたいんだと思います。

インカメラがついている海外版のGALAXY Sでは、パラメータ”camera-id”に”2”を設定することで利用することができます(参考)。

このパラメータを設定したプログラムをdocomo版GALAXY S(SC-02B)で動かしてみました…

が、ちょっと変わった、特徴的なバイブレーションの後、強制終了してしまいました。ちなみに同じプログラムをHT-03Aで動かすと、メインカメラ(リアカメラ)が動作します。つまり、単純にパラメータは無視された動作になります。

SC-02Bも単純に無視してくれた方が良い気もしますが、どうでしょう。インカメラが利用できるGALAXY Sなのか、そうでないものなのかを、何かで判別できればよいのですが、検索してみた限りではそういう情報は見つかりませんでした(先行しているAT&T版GALAXY S,  Samsung Captivateもこの辺の事情は同じだと思います)。

事前にエミュレータ(カメラは機能しません)でしか動作確認できなかったので、もしかするとプログラムに問題あるのかも?と思ってGALAXY Tabで動かしてみたところ、以下のようにちゃんとインカメラ使えました。TabもSと同じプログラミングでインカメラが利用できるようですね。

IMG_0629

インカメラに映っている自分をデジカメで撮った図です…(クリックで大きいサイズ。以下同様)

補足しますと、GALAXY Tabのカメラプレビュー解像度は、800x600と1024x600の2種類が使用でき、上図はそのうち小さい方の800x600を使っているので額縁表示になってます。1024x600の方を使用すればフル画面表示できる、はずです。

 

その他、自炊書籍の表示なども試してみました。以前Sony Reader Touch Edition(PRS-600)のキャプチャも撮ったことがあるのでこちらも参考に。

IMG_0627

週刊ダイヤモンドの電子書籍特集内、見開きでGALAXY TabとSony Readerが紹介されているページを、それぞれGALAXY TabとSony Readerで表示させてみた小ネタ写真です。

Sony Readerもそうなんですが、やはり紙の書籍と比べると光の反射が敵ですね。電車の座席で窓を背にして座って読んでいると、反射でかなり読みづらいんです…

GALAXY S/Tabで採用されているSuper AMOLEDという有機EL画面は、液晶画面と比べて、表面のガラスとその奥にある画像表示部分との隙間が小さいそうで、反射には液晶より強いとのことですが。

 

IMG_0631

週刊ダイヤモンドの2in1表示。実用的な文字の大きさではありません…拡大すれば良いじゃない、とも言えるんですが、ページごとに拡大しつつ閲覧、というのは結構面倒臭いです。インカメラで顔との距離を測り、顔を近づければ拡大、みたいなアプリを作ればあるいは。

 

galaxytab_pdf

manning社のebook(PDF)、Grails in Action(リンク先にサンプルPDFがあります)を標準アプリ?で表示させてみた図です。上下に余白ができたり、挿絵が表示されなかったりするようなので、PC向けのPDFを無変換で読む、という目論見は外れました。これについては適切なビューアアプリがあるのかもしれません。

 

IMG_0635

自炊のMore Joel on Software(A5版)。PRS-600で表示させたときは左右に余白ができていましたが、こちらはジャストなサイズです。オライリー自炊本もちょうど良い感じで閲覧できると思います。そういえば1024x600ってSony Reader Daily Edition(PRS-900)と同じ解像度ですね。

 

IMG_0619 IMG_0623

HT-03AとGALAXY S, PRS-600とGALAXY Tabとの大きさ比較です。

 

追記:

当日の内容が「触って初めて分かった――ブロガーが体感したGALAXY SとGALAXY Tabの魅力」 というPR記事で挙がっています(掲載内容有効期限:2010年11月27日)。

2010/09/26

[読書]約定率が低いことは良いことか『システム改革の正攻法』

 

正確には、システムの性能が上がったことを外部の人に示す指標として約定率の低下を用いるのは適切なんだろうか、という疑問です。

 

本書『システム改革の正攻法』の冒頭で、東証新システムarrowhead導入の効果について、以下のように記述されています。

arrowheadの導入効果は、早くもデータに表れている。代表例が東証の株式市場における「約定率」の変化だ(図1-4)。約定率とは、約定件数を全注文件数で割った値であり、これが低いほど、一般的に株式売買システムの応答スピードが速いと考えることができる。全注文に占める取消注文が相対的に多いからであり、約定までに注文と取り消しを繰り返す回数が増えたと考えることができるからだ。

引用文中の図1-4というのは、期間や表記方法は異なりますが、東証のwebサイト『arrowheadのIT Japan Award2010「経済産業大臣賞(グランプリ)」受賞について』(2010/07/05)の2つめのPDF『arrowhead(東証株式売買システム)の「①IT Japan Award2010 経済産業大臣賞(グランプリ)受賞」及び「②arrowhead稼働後6ヶ月の運転状況」について』11ページ目と同じようなものです。

上記のPDFでも『稼働前は40%以上あった約定率が、稼働後に40%を下回る水準に』と書かれているように、現在の東証は約定率低下は好ましいことである、としています。

その他、東証が約定率に関して触れている記事を探したところ、鈴木義伯東証CIOの講演『東証新売買システム(arrowhead)の開発経緯について~上流工程の取り組みとその効果~』(2010/04/27)に関して、日本システム監査人協会が発行する活動報告(SAAJ 会報)PDFにありました。

3.稼動後の状況
arrowhead 稼動後、東証自身で各種の稼動状況のデータを収集し分析を実施している。
主な指標とその傾向は以下の通りである。
(1) 注文件数/約定件数/約定率
注文件数の増加と約定件数の微増という傾向が見られる。ただし、約定率は低下傾向にあるが、これは注文の小口化が進んだ結果が要因であろうと分析している。

ここでは約定率の低下とシステム刷新の因果関係を否定しているように取れますので、途中で方向転換したのかもしれません。

余談ですが、ライブドアショック後2006/01/18に行われた記者会見の議事録PDFでは、深山浩永執行役員(当時)と記者とのやり取りで以下のように発言されており、注文の小口化と約定率の因果関係の説明に一貫性がありません。

深山「[前略]注文件数の半分程度が約定件数であろうという見方をしておりましたが、最近の傾向だと、約定率が若干増加傾向を示しているということがございます。[後略]」

記者「その背景にあるのは何ですか。」

深山「正確にはよく分からないのですが、システム発注等で細かくいっぱい成立させていくということがあるのではないかと想像されます。」

 

閑話休題。

一般的に、取引参加者から見て約定率は高い方が良いのでしょうか、低い方が良いのでしょうか。単純に考えると約定率が低いということは、買いたいのに買えない(あるいは売りたいのに売れない)という状況であるため、高い方が良さそうに思えます。

別の見方をすると、買いたくもない注文(売りたくもない注文)を出して取り消していることになりますので、見せ玉と何が違うのか、とも感じます。

また、Googleで”約定率”を検索してみると(FX業者がうざったいので-FXも指定しています)、約定率が低いことが良いことだと主張しているのはarrowhead関連の記事だけのように見えます(ちなみにFX業者は高約定率を売りにしています)。にちゃんねるのアローヘッドスレでは概ね不評のようです。

 

一方、米国のwebサイトでは、取消率の高さ(つまり約定率の低さ)”cancellation rate”はHigh-Frequency Trading(HFT)関連の話題でしばしば登場しており、賛否両論のように感じました。

これについてはSECwebサイトPress Release: SEC Issues Concept Release Seeking Comment on Structure of Equity Markets(2010/01/13)の一番下のリンク先PDF”The full text of the concept release”及びこれに対する証券会社等からのコメントを読めば現状を理解できる…と思うのですが、英語は不得意なもので…concept release「Fairness of Market Structure」節の以下の文章辺りが該当の箇所でしょうか…

Rule 605 does not require disclosure of the amount of time that canceled non-marketable orders are displayed in the order book of trading center before cancellation. Considering the high cancellation percentage of non-marketable orders, should Rule 605 require the disclosure of the average time that canceled orders were displayed in the order book?

ただ、Jun. 17, 2010 Memorandum from the Division of Trading and Markets regarding a June 16, 2010, meeting with representatives of Tradeworx, Inc. のPDFでは、取消率の高さは問題ではない、と頑なに主張しているようなので、逆に言えばSECは取消率の高さを問題にしている、少なくともSECは取消率の高さが問題ではなかろうかと提言している、のではないかと思われます。

 

そんなこんなで、「約定率が下がりました!」「おお、すごい!」となる程の共通認識は取られていないのではないか、と考えたのですが、実際のところどうなんでしょう。

 

関連エントリ: [読書]どの口が東証システム(arrowhead)開発を指して正攻法だとのたまうのか『システム改革の正攻法』

2010/09/21

[読書]彼女と二人で「C」体験!にあえてツッコむ

ストーリー上の小道具なわけで、無粋かとも思いましたので淡々と。前エントリからの流れということで…

 

出てくるソースはこれだけです。

   1: #include<empirex.h>
   2: class CHeavyInfantry : public CHoplite
   3: {
   4: public:
   5:     int ReflectAnyStrike();

CじゃなくてC++でした。クラス名がCで始まる、メンバ変数名が大文字で始まる、開きカッコの前で改行、というのはMFCのコーディング標準でしたっけ。あと、作中ではF7キーがビルドのショートカットキーになっているので、開発環境はVC6でしょうか[追記: 最新バージョンでもVCのビルドはF7でした。VC#と混同していたようです]。

p.33
ポインタのサイズは一律で4バイトです

64bit環境では通常8バイトです(参考)。この部分、作中に登場する入門書の、ポインタ変数の説明箇所の引用です。ただ、現実には、ポインタ変数が登場する段階で変数のサイズに言及するような入門書はあまり無いと思います…

p.84
「[前略]この基底クラス—"CHearvyInfantry"はC++の標準ライブラリには存在しない。[後略]」
p.88
「"重装歩兵"—"CHearvyInfantry"は、基底クラスなんです」
「このメモで定義されているのは、派生クラス。"DHoplite"のほう」

冒頭のコードの書き方だと、基底クラスはChoplite,その派生クラスがCHeavyInfantryになります。つまり説明が逆なんですが、そういうものだと思ってストーリーを読み進めていく必要があります。実在のC++とは異なるファンタジー言語を設定しているのかな、とも思いましたが、そうすると言語仕様的に変ですね(class,publicはどっちに係るんだろう)。

p.89
「クラスの継承(オーバーライド)—というものがあります。[後略]」

“継承”という漢字に”オーバーライド”というルビが振ってある箇所ですが、継承(インヘリタンス)とオーバーライドは別概念です。

p.211
「…デファインというのは、定数定義のことです」

C++で定数と言えば、const修飾した変数のことでしょう。defineの説明はこちら

 

以上です。作中ではずっとCで通してるので、このコードはCという設定かと思いきや、C++という単語も数回登場します。ところでプログラミング言語C++って絶版になったんですかね…

…見逃していました。

p.220-225

「[前略]”EX_HOPLON”に定義する、六桁の数値だ」
[中略]
「—”010831”だ」
[中略]
—1 file was successful.
の、一行を最後に、ストップする。作業が正常に終了した証だ。

頭が0だと8進数なので、本来はコンパイルエラーになります(8進数で使用できる数字は0から7まで)。実はこの数値を入力した人はコンパイル前に気づいてて…、とかだと話は広がりそうです。

2010/09/20

[読書]どの口が東証システム(arrowhead)開発を指して正攻法だとのたまうのか『システム改革の正攻法』

「システム改革の正攻法」という東証の次世代株式売買システム「arrowhead」を立ち読みして、少し違和感を感じたので購入してみました。

パラパラとめくってみて、うーん、他の人はどんな感想なんだろう、と検索してみたところ、小飼弾さんの書評

なにしろこちらにはソースコードの一部まで乗っているのだ。

という記述を見つけました。おおそんなものが書いてあったのか、と該当箇所を読んでみたところ、全く腑に落ちなかったのでまとめてみました。「第12章 スピード1000倍増の秘密 - 世界最速システムの全貌」 の 「マイクロ秒を惜しみ処理時間を削る」という節です。

p.132 図12-3に対応がまとめてありましたのでここから引用します。

tse01 

  • 設計段階で、業務ロジックを基に実行ステップ数を算出し、そこから処理時間を試算。目標時間を超えるものはステップ数削減のためにロジックや記述を見直す

○。ありだとは思いますが、この節のタイトル「マイクロ秒を惜しみ処理時間を削る」とはちょっとレベル感が違うような気はします。まあ正攻法ということで。

 

  • アプリケーション内で複数のエラー検定(チェック)処理を行う場合、当てはまる確率の高い順に記述
  • 業務処理やデータの特性に合わせた検索方法を採用

◎。これは、今回の発注者(東証)側の体制への取り組みを考えると、非常に効果的に機能したと想像します。

 

  • 呼び出し順序が決まっているいくつかのソフト部品を一つに集約、関数の呼び出し回数を削減

×。関数のインライン化、ということでしょうが、一般的には正攻法ではなくバッドノウハウです。

アンチパターンでは肥満児(The Blob)という名前が付けられています(ただしこのパターンはOOD/Pに対して適用されるもので、本システムに対しては正確な名付けではありません)。また、リファクタリングのモチベーションとなる不吉な匂いの「長すぎるメソッド」にも分類されます。

正攻法としては、関数インライン化はコンパイラに任せることです(C99ではinlineキーワードが標準化されました)。

また、強引にインライン化した際のデメリットとしては、キャッシュメモリが有効に機能しなくなる、スラッシングが発生する、といったことが挙げられます。

「ソフト部品を一つに集約」という表現が曖昧で、もしかするとダイナミックリンクをスタティックリンクに変更する、LTO(Link-Time Optimization)が効かないコンパイラへの対応(コンパイラ事情には疎いのですが、gccでは比較的最近取り入れられたそうです)、といった内容にもとれますが、いずれにせよ保守性とのトレードオフになりますので諸手を挙げて正攻法とは呼べません(どちらかというとバッドノウハウに分類されます)。

 

  • 複数のスレッドによるデータの共有を禁止(データを持ちまわりたい場合は、引数による受け渡しを利用)

×。速度向上につながる理由も分かりませんし、カッコ前後の文章のつながりも分かりません。一般的にはデータは共有した方がパフォーマンスは向上します。引数による受け渡しを行ったからといって共有が禁止できるわけではありません。スレッド間でデータを共有しない一般的な理由は、パフォーマンスに拠るものではなく並行処理におけるアクセス競合を防ぐためです。

 

  • データ操作時の関数は「memxxx」を利用(「strxxx」関数は使わない)

○。strcpy_sを使わずにmemcpyを使用する、memmoveを使わずにmemcpyを使う、といった方針であれば、パフォーマンスとセキュリティリスクのトレードオフで前者を選択したのだな、ということが明確なのですが(ただしそれが正攻法であるかどうかは別問題です)。

要するに文字列を文字列として扱わず固定長バイナリとして扱う、ということなのですが、この対応を行うことの問題点としては

    • 有効バイト以降(‘\0’以降)も意識する必要がある。本システム方針に沿って言えば、本来不要な部分の初期化、代入コストが発生する。
    • 文字列を文字列として扱っている部分との境界(例えば周辺システムとのインタフェース)でも上記を意識する必要がある。
    • 本来未初期化部分であるべきところを正しそうな値に置き換えてしまうことで、動的検査(例えばPurifyPlus)の能力を弱めてしまう。

といったことが挙げられ、個人的には△としたいです。しかし、現実のパフォーマンス差を見ると…という点で○です(私もこういう対応を行うことはありますし…)。

 

  • フラグ(1バイトデータ)の比較には、「memcmp」関数を使わずに直接データを比較
  • 1バイト以外のデータの比較には「memcmp」関数を使う

×。意味不明ですが、おそらくchar flg;char str[10];の場合の差異を言いたいのでしょう。しかしmemcmpがとる引数はvoid*型なのでそもそもchar型変数を引数にとることはできません。char*型変数が指す1バイトのデータ比較であれば、==を使おうがmemcmpを使おうがパフォーマンスは変わりません。

ところで、この記述を正確に読み取ると、intみたいな組み込み型変数もmemcmpを使うようになりますが(通常intは4バイト)、さすがにそんなことはやっていないでしょうね。

 

  • データ項目一つひとつを初期化するのでなく、初期値をセットした変数を一度にコピー(図12-5参照)

後述します。

 

  • 関数の引数にはポインタを使う、繰り返し処理内で無駄な記述をしない、冗長なチェック処理をなくす、無駄なログ出力を止める

○。当たり前と言えば当たり前なのですが、「正攻法」という観点なので。ただし繰り返し処理の中で変数宣言を行うな、といった最適化でどうとでもなるようなものだったら笑います。

ちなみに、私が担当したシステムでは、ログの重要度に応じて非同期で出力するか同期で出力するか切り替える、といったようなことも実装しました。JavaだとLog4jのAppenderで簡単に実現できみたいなんですけどね。

 

後回しにした構造体について。

 tse02

この図からわかることを列挙します。

  • 初期値の代入にはBGAA_Memcpyという関数が使われていますが、以下では文中の説明よりmemcpy相当として考えています。引数からみても、memcpyより高速なことを行っているようには見えないです。
  • コメントのついていない Filter_m[n] はアラインメント調整用のパディングメンバでしょう。OSがLinuxn=5のものがあるということは、64bitなんでしょうかね。
  • アラインメントが決め打ちです。
  • sizeof(int)などが決め打ちです。
  • 初期値をchar配列で定義しており、サイズは構造体に合わせています。

これだけでも個人的には×をつけたいところですが、移植性に関しては考慮する必要が無いという判断なのでしょうし(longを使わずにlong longを使っているところを見るとあまり吹っ切れていないようにも見えますが)、保守性について重視していないこともこれまでの対応で明らかなので、ひとまず置いておきます。

構造体の初期化、というと通常は代入を使うわけですが、それよりもmemcpyの方が高速だ、という判断でmemcpyを使用しているのですから、双方比較してみれば妥当性は確認できます。

今回使用したコードは以下になります。構造体は図12-5の上半分を用いています。また、コンパイル環境はUbuntu10.04 32bit gcc-4.4.3になります。結果は-O3で最適化しています。

   1: #include <stdio.h>
   2: #include <stdlib.h>
   3: #include <string.h>
   4:  
   5: typedef struct {
   6:     char IssueKey[16];
   7:     char SecExKbn[1];
   8:     char MktKbn[2];
   9:     char IssueCd[12];
  10:     char IssueKbn[4];
  11:     char Filter_1[5];
  12:     long long Irate;
  13:     long long RepP;
  14:     char YldRstrn[1];
  15: } LAA01_t;
  16:  
  17: const static LAA01_t init_value = {
  18:     {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20},
  19:     {0x20},
  20:     {0x20,0x20},
  21:     {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20},
  22:     {0x20,0x20,0x20,0x20},
  23:     {0x20,0x20,0x20,0x20,0x20},
  24:     0,
  25:     0,
  26:     {0x20}
  27: };
  28:  
  29: const static char init_value_char[sizeof(LAA01_t)] ={
  30:     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
  31:     0x20,
  32:     0x20,0x20,
  33:     0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
  34:     0x20,0x20,0x20,0x20,
  35:     0x20,0x20,0x20,0x20,0x20,
  36:     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  37:     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  38:     0x20
  39: };
  40:  
  41:  
  42:  
  43: void assign_operator(LAA01_t *t1, const LAA01_t *t2){
  44:     *t1=*t2;
  45: }
  46:  
  47: void assign_memcpy(LAA01_t *t1, const LAA01_t *t2){
  48:     memcpy(t1,t2,sizeof(LAA01_t));
  49: }
  50:  
  51: void assign_memcpy_char(LAA01_t *t1, const char *c){
  52:     memcpy(t1,c,sizeof(LAA01_t));
  53: }
  54:  
  55:  
  56: int main(int argc, char** argv) {
  57:     LAA01_t t1, t2, t3;
  58:  
  59:     assign_operator(&t1,&init_value);
  60:     assign_memcpy_char(&t2,init_value_char);
  61:     assign_memcpy(&t3,&init_value);
  62:  
  63:     printf("%s[end]\n",t1.IssueKey);
  64:     printf("%s[end]\n",t2.IssueKey);
  65:     printf("%s[end]\n",t3.IssueKey);
  66:     return (EXIT_SUCCESS);
  67: }
  68:  

上記コードの説明を簡単に行います。

  • 初期値としてinit_valueという構造体を定義しています。
  • 東証のコード相当の初期値はchar配列のinit_value_charです。
  • assign_memcpy_charはmemcpy関数でchar配列から値をコピーする関数です。東証のコード相当です。
  • assign_operatorは代入演算子で代入する関数です。
  • assign_memcpyはmemcpy関数で構造体から値をコピーする関数です。参考として作成してみました。

つまり、assign_memcpy_char関数とassign_operatorの差が、memcpyを利用して初期値を設定することのメリットになります。上記コードをコンパイル後、objdump -dコマンドでアセンブラコードを表示し、比較しました。

アセンブラについての知識は全く無いに等しいので検証できるか不安でしたが、杞憂に終わりました。以下がそれぞれの関数の部分についてのコードになります。

   1: 080484e0 <;assign_memcpy_char>:
   2:  80484e0:    55                       push   %ebp
   3:  80484e1:    89 e5                    mov    %esp,%ebp
   4:  80484e3:    8b 55 0c                 mov    0xc(%ebp),%edx
   5:  80484e6:    8b 45 08                 mov    0x8(%ebp),%eax
   6:  80484e9:    8b 0a                    mov    (%edx),%ecx
   7:  80484eb:    89 08                    mov    %ecx,(%eax)
   8:  80484ed:    8b 4a 04                 mov    0x4(%edx),%ecx
   9:  80484f0:    89 48 04                 mov    %ecx,0x4(%eax)
  10:  80484f3:    8b 4a 08                 mov    0x8(%edx),%ecx
  11:  80484f6:    89 48 08                 mov    %ecx,0x8(%eax)
  12:  80484f9:    8b 4a 0c                 mov    0xc(%edx),%ecx
  13:  80484fc:    89 48 0c                 mov    %ecx,0xc(%eax)
  14:  80484ff:    8b 4a 10                 mov    0x10(%edx),%ecx
  15:  8048502:    89 48 10                 mov    %ecx,0x10(%eax)
  16:  8048505:    8b 4a 14                 mov    0x14(%edx),%ecx
  17:  8048508:    89 48 14                 mov    %ecx,0x14(%eax)
  18:  804850b:    8b 4a 18                 mov    0x18(%edx),%ecx
  19:  804850e:    89 48 18                 mov    %ecx,0x18(%eax)
  20:  8048511:    8b 4a 1c                 mov    0x1c(%edx),%ecx
  21:  8048514:    89 48 1c                 mov    %ecx,0x1c(%eax)
  22:  8048517:    8b 4a 20                 mov    0x20(%edx),%ecx
  23:  804851a:    89 48 20                 mov    %ecx,0x20(%eax)
  24:  804851d:    8b 4a 24                 mov    0x24(%edx),%ecx
  25:  8048520:    89 48 24                 mov    %ecx,0x24(%eax)
  26:  8048523:    8b 4a 28                 mov    0x28(%edx),%ecx
  27:  8048526:    89 48 28                 mov    %ecx,0x28(%eax)
  28:  8048529:    8b 4a 2c                 mov    0x2c(%edx),%ecx
  29:  804852c:    89 48 2c                 mov    %ecx,0x2c(%eax)
  30:  804852f:    8b 4a 30                 mov    0x30(%edx),%ecx
  31:  8048532:    89 48 30                 mov    %ecx,0x30(%eax)
  32:  8048535:    8b 4a 34                 mov    0x34(%edx),%ecx
  33:  8048538:    89 48 34                 mov    %ecx,0x34(%eax)
  34:  804853b:    8b 52 38                 mov    0x38(%edx),%edx
  35:  804853e:    89 50 38                 mov    %edx,0x38(%eax)
  36:  8048541:    5d                       pop    %ebp
  37:  8048542:    c3                       ret    
  38:  8048543:    8d b6 00 00 00 00        lea    0x0(%esi),%esi
  39:  8048549:    8d bc 27 00 00 00 00     lea    0x0(%edi,%eiz,1),%edi
   1: 08048470 <;assign_operator>:
   2:  8048470:    55                       push   %ebp
   3:  8048471:    89 e5                    mov    %esp,%ebp
   4:  8048473:    8b 55 0c                 mov    0xc(%ebp),%edx
   5:  8048476:    8b 45 08                 mov    0x8(%ebp),%eax
   6:  8048479:    8b 0a                    mov    (%edx),%ecx
   7:  804847b:    89 08                    mov    %ecx,(%eax)
   8:  804847d:    8b 4a 04                 mov    0x4(%edx),%ecx
   9:  8048480:    89 48 04                 mov    %ecx,0x4(%eax)
  10:  8048483:    8b 4a 08                 mov    0x8(%edx),%ecx
  11:  8048486:    89 48 08                 mov    %ecx,0x8(%eax)
  12:  8048489:    8b 4a 0c                 mov    0xc(%edx),%ecx
  13:  804848c:    89 48 0c                 mov    %ecx,0xc(%eax)
  14:  804848f:    8b 4a 10                 mov    0x10(%edx),%ecx
  15:  8048492:    89 48 10                 mov    %ecx,0x10(%eax)
  16:  8048495:    8b 4a 14                 mov    0x14(%edx),%ecx
  17:  8048498:    89 48 14                 mov    %ecx,0x14(%eax)
  18:  804849b:    8b 4a 18                 mov    0x18(%edx),%ecx
  19:  804849e:    89 48 18                 mov    %ecx,0x18(%eax)
  20:  80484a1:    8b 4a 1c                 mov    0x1c(%edx),%ecx
  21:  80484a4:    89 48 1c                 mov    %ecx,0x1c(%eax)
  22:  80484a7:    8b 4a 20                 mov    0x20(%edx),%ecx
  23:  80484aa:    89 48 20                 mov    %ecx,0x20(%eax)
  24:  80484ad:    8b 4a 24                 mov    0x24(%edx),%ecx
  25:  80484b0:    89 48 24                 mov    %ecx,0x24(%eax)
  26:  80484b3:    8b 4a 28                 mov    0x28(%edx),%ecx
  27:  80484b6:    89 48 28                 mov    %ecx,0x28(%eax)
  28:  80484b9:    8b 4a 2c                 mov    0x2c(%edx),%ecx
  29:  80484bc:    89 48 2c                 mov    %ecx,0x2c(%eax)
  30:  80484bf:    8b 4a 30                 mov    0x30(%edx),%ecx
  31:  80484c2:    89 48 30                 mov    %ecx,0x30(%eax)
  32:  80484c5:    8b 4a 34                 mov    0x34(%edx),%ecx
  33:  80484c8:    89 48 34                 mov    %ecx,0x34(%eax)
  34:  80484cb:    8b 52 38                 mov    0x38(%edx),%edx
  35:  80484ce:    89 50 38                 mov    %edx,0x38(%eax)
  36:  80484d1:    5d                       pop    %ebp
  37:  80484d2:    c3                       ret    
  38:  80484d3:    8d b6 00 00 00 00        lea    0x0(%esi),%esi
  39:  80484d9:    8d bc 27 00 00 00 00     lea    0x0(%edi,%eiz,1),%edi
   1: 08048550 <;assign_memcpy>:
   2:  8048550:    55                       push   %ebp
   3:  8048551:    89 e5                    mov    %esp,%ebp
   4:  8048553:    8b 55 0c                 mov    0xc(%ebp),%edx
   5:  8048556:    8b 45 08                 mov    0x8(%ebp),%eax
   6:  8048559:    8b 0a                    mov    (%edx),%ecx
   7:  804855b:    89 08                    mov    %ecx,(%eax)
   8:  804855d:    8b 4a 04                 mov    0x4(%edx),%ecx
   9:  8048560:    89 48 04                 mov    %ecx,0x4(%eax)
  10:  8048563:    8b 4a 08                 mov    0x8(%edx),%ecx
  11:  8048566:    89 48 08                 mov    %ecx,0x8(%eax)
  12:  8048569:    8b 4a 0c                 mov    0xc(%edx),%ecx
  13:  804856c:    89 48 0c                 mov    %ecx,0xc(%eax)
  14:  804856f:    8b 4a 10                 mov    0x10(%edx),%ecx
  15:  8048572:    89 48 10                 mov    %ecx,0x10(%eax)
  16:  8048575:    8b 4a 14                 mov    0x14(%edx),%ecx
  17:  8048578:    89 48 14                 mov    %ecx,0x14(%eax)
  18:  804857b:    8b 4a 18                 mov    0x18(%edx),%ecx
  19:  804857e:    89 48 18                 mov    %ecx,0x18(%eax)
  20:  8048581:    8b 4a 1c                 mov    0x1c(%edx),%ecx
  21:  8048584:    89 48 1c                 mov    %ecx,0x1c(%eax)
  22:  8048587:    8b 4a 20                 mov    0x20(%edx),%ecx
  23:  804858a:    89 48 20                 mov    %ecx,0x20(%eax)
  24:  804858d:    8b 4a 24                 mov    0x24(%edx),%ecx
  25:  8048590:    89 48 24                 mov    %ecx,0x24(%eax)
  26:  8048593:    8b 4a 28                 mov    0x28(%edx),%ecx
  27:  8048596:    89 48 28                 mov    %ecx,0x28(%eax)
  28:  8048599:    8b 4a 2c                 mov    0x2c(%edx),%ecx
  29:  804859c:    89 48 2c                 mov    %ecx,0x2c(%eax)
  30:  804859f:    8b 4a 30                 mov    0x30(%edx),%ecx
  31:  80485a2:    89 48 30                 mov    %ecx,0x30(%eax)
  32:  80485a5:    8b 4a 34                 mov    0x34(%edx),%ecx
  33:  80485a8:    89 48 34                 mov    %ecx,0x34(%eax)
  34:  80485ab:    8b 52 38                 mov    0x38(%edx),%edx
  35:  80485ae:    89 50 38                 mov    %edx,0x38(%eax)
  36:  80485b1:    5d                       pop    %ebp
  37:  80485b2:    c3                       ret    
  38:  80485b3:    8d b6 00 00 00 00        lea    0x0(%esi),%esi
  39:  80485b9:    8d bc 27 00 00 00 00     lea    0x0(%edi,%eiz,1),%edi

全て同一です。ちなみに最適化しない場合は、memcpyを利用するとインライン化されず関数コールが増える分、memcpyを利用する方がコスト増です。

今回はソースコードを書いて試してみましたが、そもそも、なぜコンパイラは最適な代入処理を行ってくれない、という考えに至るのでしょうか。

上記のような対応を行った結果、保守性、移植性を低下させたにも関わらず、パフォーマンスには全く寄与しない(どころか低下させる可能性がある)ものになっています。評価としては二重×どころでは済みません。

 

これまで示してきた内容より、この書籍が言うところの「正攻法」とは、バッドノウハウを駆使してでもarrowheadの第一優先目標である速度向上を叶える、というものです。しかし一般的にはそれを正攻法とは呼びません。

以上、小飼さんの書評がきっかけということもあり、久しぶりにこちらを意識して書いてみました。

 

最後に。本書の中で鈴木義伯東証CIOが「技術者冥利に尽きる」とおっしゃっていらっしゃることについて。

このような巨大システム構築プロジェクトを予定通り(で良いんでしたっけ?当初は2009年秋だったような気もしますがこれは忘れます)完遂できた、情報システムの最高責任者であるCIOのプロジェクトマネジメント能力は並大抵のものではないと思われます。正直、私は2010年1月4日にarrowheadが稼働できるとは思っていませんでした。

しかし、私が同じような立場に立ったとするならば、目標を達成するために上で述べてきたような(仮に全て速度向上に繋がるとしても)泥臭い対応を行わなければならなかったことや、21世紀にもなってこのような保守性の低いシステムを見続けなければならないだろう若いSEのことを考えると、「技術者冥利に尽きる」などとは決して言うことはできないでしょう。万が一そのような言葉を吐かなければならない状況が予想されるのであれば、ここで記載したような対応をオープンにはしないでしょう。

この「技術者」についての価値観の違いが、冒頭に記載した違和感の正体かな、と考えます。

というか冒頭で示した小飼さんの書評、

全く奇をてらったことがない。まさに正攻法。愚直といってもいい。

自身で示した箇所の内容もちゃんと読んでませんよね…?

 

プログラミング的な部分以外にも言いたいことは出てきそうな予感がしますが、それはまた気が向けば。

other sites

  • follow us in feedly
  • github
  • stackoverflow

ソフトウェアエンジニアとして影響を受けた書籍

  • Christain Bauer: HIBERNATE イン アクション

    Christain Bauer: HIBERNATE イン アクション
    理論と実践が双方とも素晴らしい製品であるHibernate。本書はそのプロダクトを書名に冠していますが、Hibernateを使うつもりがなく、ORマッピングの解説書として読むにしても十分な良書です。Second EditionとしてJava Persistence With Hibernateという書籍も出版されていますが、残念ながら現在のところ 和訳はされていません。-インアクションは2.xの、Java Persistence-は3.1の頃のものなので、最新版とはちょっと違うところもあることに注意。 (★★★★★)

  • アンドリュー・S・タネンバウム: 分散システム 原理とパラダイム 第2版

    アンドリュー・S・タネンバウム: 分散システム 原理とパラダイム 第2版
    クライアント/サーバシステムを構築する上で必要となる知識が総論されてます。Web技術者も、フレームワーク部分を開発するのであれば必読。 (★★★★★)

  • Joel Spolsky∥著: ジョエル・オン・ソフトウェア

    Joel Spolsky∥著: ジョエル・オン・ソフトウェア
    前述の書籍「ソフトウエア開発プロフェッショナル」をより砕いたもの、という感じでしょうか。 前書きではプログラマでなくSE向けの本のように書かれているが、プログラマが読んでも面白い本であると思われます。 SEになった新人(あるいはそういう会社に入る/入りたての人)にとっては、これからどういったことが仕事を遂行していく上で起こりえるのか、どのように考えて行なっていけばいいのか決定する助けになると思います。 元は″Joel on Software″というブログの記事で、web上でも一部日本語で読めます。 http://japanese.joelonsoftware.com/ (★★★)

  • ドナルド・C・ゴース,ジェラルド・M・ワインバーグ: ライト、ついてますか

    ドナルド・C・ゴース,ジェラルド・M・ワインバーグ: ライト、ついてますか
    問題解決(一昔前のの流行語で言うところの『ソリューション』)能力は、システムエンジニアのスキルとして備えるべきもののうちのひとつです。しかし、これは難しい。学校で出されるテストと違い、唯一の、(問題提出者が想定している)解を求めるだけが「問題解決」では無いからです。そもそも、何が問題なのか、それは本当に問題なのか、それは本当に解決すべき問題なのか、その問題解決方法は正しいのか、などを解決しなければ、「その解は正しいのか」に辿りつくことができません。この本の最も良いところのひとつは、本があまり厚くないこと。すぐに読めるし、何回も読み返す気になるでしょう。 (★★★★★)

  • スティーブ・マコネル: ソフトウエア開発プロフェッショナル

    スティーブ・マコネル: ソフトウエア開発プロフェッショナル
    コードコンプリートで有名なスティーブマコネルの著書。新人SEに読んで欲しい。個人として業界の中でどうあるべきか、組織としてどうあるべきか、SEのプロ意識とは?SEの心構え概論、といったところでしょうか。また、業界における資格の重要性についても説かれています。この業界では資格が特に軽んじられる傾向がありますが、この傾向はどんな弊害をもたらすのか、将来的にこの業界は資格に対してどのような姿勢で臨んでいくべきなのか。日経BP社では(他の出版社もだが)最近、似たような類いのあまり面白くない書籍が乱出版されていますが、この本は別格だと思うので安心して購入して欲しいと思います。 (★★★★★)

無料ブログはココログ