How IT Works

プログラマーやっています。技術よりも人間学的なところが好きです。

2016年に読んで印象に残った本

前書き

 最近、今年を振り返るエントリーをよく見かけるので、便乗して書きます。

 自分の場合年間読んでいる本は大体200冊くらい行くと思います。技術書5割、漫画2割、ライトノベル1割、その他2割というところでしょうか。

 あまりマイナーな作品は読まないのですが、それでも人に勧められるくらいには本は読んでいると思うので、書いてみます。

技術書

CSSシークレット

 本自体をCSSとHTMLで書いたという意欲作です。

 例えば、台形の描画をどうすればCSSで記述できるのか?という問いを2~6ページくらいをかけてといていくという形式で進んでいきます。

 CSS3で新しくできたプロパティを使って解決することが多いのですが、発想が少し飛んでいて業務で使うレベルをはるかに超えています。

 CSSを極める本というのが一番近いでしょうか。CSSには自信がある! という人にこそお勧めできます。

 自分もそれなりにCSSに慣れてきたと思っていたのですが、デザインセンスや技術へのこだわりのレベルの違いを強く感じながら読みました。

Web制作者のためのCSS設計の教科書

 こちらもCSSに関する本です。

 上記の本はCSSの技術について深く踏み込んでいくような本でしたが、こちらはCSSの最新スタイルについてわかりやすく説明してくれる本です。

 オブジェクト指向CSSとかBEMといった実際の業務に応用しやすい内容です。

 CSSの文法や書き方はわかっても、そこからどうやって進めばいいかと思っていたところでこの本に出会いました。

 CSS初心者から一つレベルを上げるには良い本です。

JavaScript Ninjaの極意

 タイトルで引いてはいけません。正直、自分もこのノリについていけないのではないかと心配しながら購入しました。

 中身も多少ユーモアに富んでいてまじめという感じではありませんが、JavaScriptの書籍の中ではダントツで面白かったです。

 CSSシークレットよりはどちらかといえば業務で使えそうな内容ですが、JavaScriptの機能を使い倒すという感じのコードが多く、はっとすることが多いです。

 実際的にはライブラリ、例えばJQueryやAngularを使っていれば、この本のレベルの知識はいらないのかもしれません。ただ、よりよいコードを書くということを考えたときに、ぜひこの本を読んでほしいと思います。

 JavaScriptは欠陥をよく指摘されますが、機能をフルに使えるととても楽しい言語です。なので、ぜひこの本を手にとってもらえたらと思います。

JavaScript Ninjaの極意 ライブラリ開発のための知識とコーディング (Programmer's SELECTION)
ジョン・レシグ John Resig ベア・ビボー Bear Bibeault
翔泳社
売り上げランキング: 133,870

漫画・ライトノベル

神様のバレー

 簡単にいうと、バレーの実業団を日本一に導いたデータアナリストが進学校の中学生に指導することとなり、全国優勝を目指すという漫画です。

 あらすじからわかるように、戦略、データといったものを楽しむ漫画で、ジャイアントキリングに似ています。

 主人公のコーチは本当に綿密に計画を立ててながら試合を進めていくので、自分だったらどういう作戦を立てるだろうかということを考えながら読めます。

 今年読んだ漫画の中では一番面白いです。

神様のバレー 1巻 (芳文社コミックス)
芳文社 (2014-06-27)
売り上げランキング: 24,563

サツリクルート

 タイトルの通り、殺戮+リクルートが主題の漫画です。

 就活生のうち、アクマに選ばれたものは契約を交わし、能力を得ます。「面接官のリアクションを倍増させる能力」や「面接官を惚れさせる能力」などです。

 その代わり、就職試験に落ちたら、命を奪われます。

 かなりぶっとんだ設定ですが、かなり爽快なストーリーにまとまっていて、面白いです。

 主人公たちは一応まじめに就活してるのでシュールな感じもしますが、納得できるようにオチをつけているのは本当にすごいです。

 興味があれば、裏サンデーをのぞいてみるといいでしょう。

urasunday.com

東雲侑子は短編小説をあいしている

 ライトノベルですが、ほどよく現実的な青春小説です。とても純粋できれいな恋が表現されていて、何度でも読みたくなる本です。

 嫉妬や将来への不安、相手への恨みといった暗い感情も出てきますが、それを飲みこみながら前に進んでいく感じが素敵です。

 基本的に自分は一般小説よりライトノベルが好きなのですが、それは人間賛歌の話が多いからです。現実的であることよりも、きれいな夢を見せてくれる話がすきで、まさにこのライトノベルはドンピシャでした。

 少し古くなっていますが、ぜひ読んでみてほしい作品です。3巻でまとまっているので、まとめて読めるのもいいですね。

 あと、主人公の東雲さんは本当にかわいいです。

趣味

サプライズプレゼント―大切な人を喜ばせる贈り物集

 サプライズプレゼントというと、例えば結婚式の動画や卒業生への色紙などが思い浮かびます。

 そういうときに「みんなこうしているからこれで、いいか」と納得しがちです。

 でも、ちょっと待ってください。人を喜ばせる方法はあなたが考えている以上にたくさんあります。例えば、

  • 無地のジグソーパズルにメッセージやイラストを書いて、プレゼントする。
  • 同級生の写真を印刷したオリジナルかるたを作り、それで遊ぶ。
  • クリスマスに時間指定して、愛の言葉を書いた手紙を届けてもらう。
  • プレゼントとして名刺入れをあげる。そのなかに、相手への気持ちを書いた名刺を入れておく。

 この本には本当にたくさんのアイディアがあります。あぁ、こんなアイディアがあったのか、と1ページごとに感動します。

 サプライズ好きの自分としてはよくネットで調べたりするのですが、この本以上にいいアイディアはそうそうないと思います。

 今年買った本の中では一番、影響を受けた本です。

サプライズプレゼント―大切な人を喜ばせる贈り物集
篠原 一貴 喜ぶ笑顔.com
ロコモーションパブリッシング
売り上げランキング: 615,574

まとめ

 200冊読んだ割りには、印象に残った本はすんなり出せました。役に立つ本は多いですが、感動できる本にはあんまり出会えていないのかなぁという気がします。

 特に趣味関連が少ないですね。どうしても読んでいる本のバリエーションが少ないので、時間があればもっといろいろな分野にとり組めたらいいのかなぁと思います。

 とはいえ、ここにあげた本はかなりお勧めできるものばかりです。ぜひ、一度は目にとってもらえたらうれしいです。

最近使ってみたツールと感想

前書き

 タイトルの通りです。最近使ってみたツールとその感想を書きます。

Slack

背景

 自分の会社のチャットツールはSkypeなので、今人気のSlackとはこれまで縁がありませんでした。しかし、下記のような記事を見つけて、勇気づけられました。

個人 Slack のススメ - Qiita

 一人でも大丈夫なんだと思い、思いきってSlackを使ってみました。

所感

Slackはご存知の通りチャットツールなのですが、自分はほぼメモ用途で使っているだけです。

 使ってみた感想としては、端的に使いやすいです。入力が簡単でレスポンスが早いです。それにメッセージの削除、編集が簡単なので助かります。

 今までメモ用途ではLineで一人しかいないグループを使っていましたが、こちらよりSlackのほうがはるかに手軽だと断言できます。

 スマートフォン用のアプリがあるのもいいです。

使っているチャンネル

  • todo
    • やるべきことをメモ。
  • memo
    • なんでも思ったことをメモ。
    • 消さない。
  • link
    • 気になったリンクをメモ。
    • 見やすい。
  • neta
    • ブログのネタ
  • diary
    • 日記

課題

 上記の筆者はRSSフィードtwitterをSlackに流して……という感じで運用していますが、ここら辺の感覚がまだピンときていない感じです。

 RSSは試してみたのですが、どうも別のクライアントを立ち上げるほうが楽でした。もう少し色々なものを流しながら、試してみようと思います。

Feedly

背景

 FeedlyRSSリーダーの1つです。基本的には英語です。

feedly. Read more, know more.

 もともとGoogle Readerを使っていたのですが、サービスが中止されたのでしばらくLive Dwango Readerに移っていました。

 ただ諸事情でRSSリーダーを分ける必要が出てきたので、せっかくなので別のRSSリーダーに移ることにしました。

所感

 とても見やすいです。英語なのもほとんど気になりませんし、Readerの見出しがサッと画面にでてくれるのがとてもありがたいです。

 LiveDwangoReaderの場合、すべての情報を最初に読み込みに行くので全文読まないと概要がつかめませんし、なにより遅いのが嫌でした。

 Feedlyは見出しもそうですし、すべての動きが警戒です。情報収集の速度がぐんと変わるので変えてよかったと思います。

 こちらもスマートフォンのアプリがあるようですが、基本的にRSSReaderはパソコンでしか見ないので使ったことがありません。

Toggle

背景

 Toggleは時間を管理してくれるWebサービスです。

 Toggl - Free Time Tracking Software

 趣味で作ろうとしているアプリが習慣管理系統なので、参考にならないかと思って導入してみました。

 基本的には時間を記録して、日々の行動を可視化するツールです。ボタンを押すと自動で時間を計ってくれます。

 何人かのプロジェクトで全員の作業と時間も共有できるようです。

所感

 UIはとても使いやすいです。入力がしやすいですし、動作も直観的です。

 シンプルでとてもわかりやすいツールで、基本的な機能は網羅しているように思います。

 ただ、やってみると自分はもう少し複雑なことをしたいんだなーと実感しました。もう少しタスクの階層をいじったり、反省を書いたり、予定を書いたりと色々なものと結びつけて時間を管理するとか。

 作りたいアプリの参考にはなりましたが、自分のやりたいこととは違うのであんまりピンとこなかったです。

まとめ

 色々とアプリを入れてみたのですが、最近のWebアプリは何となくデザインが似ていますね。最近のはやり何でしょうか。

 プログラマーとして自分はあまりアプリを使わないほうなのですが、最近の流れなどをするためにももう少し色々便利なものを取り入れていけたらいいなと思いました。

ASP.NET+Angular1.x+TypeScriptでTodoアプリのサンプルを作りました

前書き

 タイトルの通りAngular1.x系を使って、Todoアプリを作ってみました。

 基本的にはページを閉じるとデータが消えてしまうので実用性はありませんが、技術的な参考にはなるんじゃないかと思います。

github.com

完成イメージ

f:id:dexia2:20161218114830j:plain:w300

使用した技術

 GitHubのREADMEにも書きましたが、こちらにも一応書きます。

  • ASP.NET Core
    • VS2015で作成
    • APIとWebともに、ASP.NET Core上で動かしています。
    • C#
  • Angular1.x
    • Angular Resource
  • BootStrap
  • JQuery UI
  • TypeScript

特徴

Single Page Application(SPA)

 このアプリはページ遷移を行わないようなSPAになっています。画面の更新は基本的にAngularに任せるようにしています。

 また、データの取得はWebAPI経由で取得しています。更新や削除は今のところインメモリでやっています。

Windows FormsっぽいUI

 UIはJQueryUIのDialogを使用しています。

 この技術を選択した理由としてはAngularとの相性が良さそうだったからです。他のダイアローグのライブラリはiframeを使っているものが多く、Angularらしさがあまり出せない感じでした。

 その点、JQueryUIのDialogはDOMでダイアローグを表現するので、そのままAngularと組み合わせることができました。

 Angularと組み合わせているところは下のよう感じです。

// 画面のキーの採番
var guid = this.getGuid();

//ダイアローグを開く
$(`<div class = "dialog" id = ${guid}></div>`).dialog(dialogOption);

//ダイアローグにAngularのviewを差し込む
var $dialog = $(`#${guid}`);
var includeHtml = `<div ng-include="'${config.path}'"></div>`
var scope = angular.element($dialog).scope();
$dialog.append(this.$compile(includeHtml)(scope));

 viewの展開はng-includeを使っています。これをコンパイルして、ダイアローグに差し込むことで画面を表現しています。

 ちなみにGUIDが出てきていますが、これは画面のインスタンスごとの固有のIDになります。これを使って、画面を閉じたり、返り値をとったり、パラメータを受け渡ししたりしています。

TypeScriptらしい書き方

 TypeScriptを利用しているので、できる限りfunctionではなくクラスを渡してサービスやコントローラを定義するようにしています。

/**
 * Todoサービス
 */
class TodoService {
//省略。。。
}

app.service("TodoService", [
    "$resource",
    TodoService
]);

感想

 普通、Angular1.xを使ったSPAというとui-routerを使うものなのでこれは少し邪道な感じもしますが、一応SPAではあります。

 現状だと、戻る機能が使えなかったり、URLでの遷移ができないという欠点はありますが。

 とはいえ、Angular1.xの基本的な機能の使い方は押さえていて、Windows開発でよく使う技術(ASP.NETC#+TypeScript)で書いたので参考にはなるかなとは思います。

 興味があれば見てみてください。

生産性を高める習慣

生産性を高めるもの

 プログラマーであれば誰でも、「より少ない工数で問題を解決できる技術」を身につけるべく日々努力していると思います。

 新しいツールを導入したり、新しい設計方法を試してみたり、既知の問題は極力自動化したり……、様々な方法で生産性の向上に努めているはずです。

 こうした解決方法も常に導入していくべきだとは思うのですが、個人的にはまず個々人が自分の能力を出しきることが大事だと思っています。

 プログラマーとしての生産性というと知識量や経験がやはり重要だとは思うのですが、それ以外でも

  • 集中力の高さ
  • 視界の広さ
  • 論理的な思考力
  • 問題解決のための想像力

 といったアナログ的な能力も同じように高めていく必要があると感じています。

 一朝一夕でこうした能力を身につけることはできませんが、習慣を変えることである程度までは生産性を補うことができます。

 今回はそうした習慣について書きます。

生産性を高めるための習慣

焦っていることに気付く

 プログラミングをしていて難しい問題に当たると、どうしてもパニックになることがあります。

 そういうときはとにかく落ち着くことです。パニックになるときは大抵同時に2つ以上のことを考えているです。

 止まるということはとても難しいです。なんとなく答えが出そうという状況だと、もう少し頑張れば行けるんじゃないかという気持ちになります。

 そういう気持ちを抑えて、できる限り1つずつ小さな問題に分解して解いていくことです。これができるとできないでは、問題解決能力がずいぶん変わるように思います。

とにかく表現してみる

 プログラミングで詰まった時はいつでも、白紙の紙に思いついたことを書くようにしています。

 UMLだったり、アーキテクチャの図であったり、単語の羅列だったり、色々とパターンはありますが、困った時は何かしら視覚化してみると問題がよく見えるようになってきます。

 また、困った時は誰か捕まえて、相談してみるといいと思います。

 プログラミング上の問題を相談相手が解決してくれることはあまりないのですが、人に話すことで問題の全体像が見えてきます。

 問題の分解もそうですが困った時に、1歩立ち止まって別のアプローチをできると、問題解決のスピードはぐんと上がるように感じます。

 ちなみに、自分は会社のデスクにはいつもこのスケッチブックを置いておいて、何か思いつくたびに書きつけています。

 小さなアイディアやTodoはこれくらいの小さい紙がいいですね。所詮100円なので、躊躇せずに書けるのがいいです。いい悪い関係なくとにかく書くことで頭が働きます。

 うちの会社の優秀な技術者はみんな白紙の紙をいつも持ち歩いているので、やはり思考にとって表現は大事なんだろうと思います。

 そして、みなさんとにかく図やイラストでの表現がとてもうまいです。論理だけでなく、図解思考というのができているんでしょうね。

責任を持つ

 誰かが何とかしてくれる、どうせ納期には間に合わないという他人任せな思考をしていると生産性は落ちます。

 無茶な納期・仕様変更や不当な人事評価など理不尽なことを押し付けられると、責任を放棄したくなる瞬間は来ますが、そこで我慢してやるべきことができるのがプロの技術者だと思います。

 それに無茶に対してどのように対処できるのかというところを考えて仕事することで、プログラマーの能力というのは向上するものです。

 そのため、できる限り自分の仕事に責任を持ちましょう。そして、言われた納期で最高の品質を目指すようにしましょう。

 最初は理不尽に感じることのほうが多いですが、この習慣の有無が将来的に大きな差になると思います。

定時に帰ることを目指す

 残業してもいいと考えると、生産性はぐんと落ちます。納期がない仕事と同じようにだらだらしがちです。

 そのため、開き直って毎日定時で帰りつつ、任された仕事をこなせるように努力しましょう。

 こちらのほうが高い集中力をキープできますし、効率よく仕事をこなす方法を考えるようになります。

 そのため、最初から残業を頭に入れるような働き方ではなく、絶対に定時で変えると決めて働いたほうが自分の成長につながると思います。

集中を使いこなす

 集中している時間=作業時間です。集中していない時間は仕事の中ではできるだけ、減らしていかないといけません。

 大事なことは、細かい作業を間に入れないことだと思っています。電話もそうですし、メール・RSSReaderの処理などが作業の途中で入ると集中が切れやすくなります。

 そのため、できるかぎりそういった細切れの作業はプログラミング中に入れないように努力します。

 また、集中できる時間帯が誰にでもあります。自分は朝と昼一です。こういう時間に難しい作業を当てて、簡単な作業は後に回すようにします。

 あとは、集中するのには訓練がいると思います。毎日できる限り自分のできる最高の集中力を発揮する時間を作ったほうがいいと思います。

 人と話したり、twitterを見ながらだらだら作業する習慣がついてしまうと、それが癖になります。そのため、1日のある時間は一人でひたすら集中する訓練を積んでおくと生産性が上がります。

まとめ

 あたりまえのことが増えすぎて思ったようには行かなかったのですが、こういった思考や集中といったテーマに毎日取り組んでいくことが大事だと思います。

 どうしても、新しい技術や知識ばかり追いがちになるので、こういった無形の力もスポーツと同じでトレーニングしていくことでよりよい技術者になりたいです。

 今回の記事のような話は以下の本が詳しいです。

 浅く広くという感じでほとんど自己啓発本のような感じですが、納得できることは多いです。

 興味があれば、手を出してみるといいと思います。

来年の年賀状を作りました(2017年)

前書き

 そろそろ年が明けるということで、来年(2017年)の年賀状を作成してみました。

 年賀状というよりはクリスマスのメッセージカードみたいになっていますが、まぁまぁきれいにできたと思います。

f:id:dexia2:20161214211659p:plain:w300

 ただ作っても作業になってしまうので、HTMLとCSSを使ってデザインしました。

 ソースは以下で。

github.com

 できるだけ、シンプルにということで純粋なCSSとHTMLで組みました。アクセシビリティとか、アウトラインとかCSSの詳細度 といった細かいところはもう少し直すかもしれません。

 CSSとHTMLはほぼ初心者なのでソースで気になることがあれば、ご指摘ください。

技術的なところ

 雪は基本的にすべてHTMLとCSSで表現しています。

 少し省略していますが、以下のような感じです。

--HTML

  <section class="sky">
    <div class="snows">
        <div class="snow snow1"><div class="crystal"></div></div>
    </div>
  </section>

--CSS

.sky .snow {
  position: absolute;
}

.sky .snow .crystal {
  padding:50%;
  border-width: 1px;
  border-radius: 50%;
  border-color: #41719C;
  border-style: ridge;
  background-color: #FFF;
}

.sky .snow.snow1 {
  width: 4.25%;
  top: 5%;
  left: 5%;
}

 雪は基本的にシンプルに枠線で表現しています。ここで意識して書いたこととしては、

  • 円をCSSだけで表現する。(border-radius: 50%)
  • 雪をレスポンシブ対応にする。(padding:50%;やwidth: 4.25%;などできるだけ%で指定)
  • 雪の座標の指定の仕方。

 などでしょうか。文字をいれた雪も基本的にはおなじ方法です。
 文字の部分だけ下に表示しておきます。

--HTML

  <section class="sky">
    <div class="snows">
      <div class="snow message-snow message-snow1">
        <div class="crystal"></div>
        <div class="snow-message"></div>
      </div>
  </section>

--CSS

.sky .snow.message-snow .snow-message {
  position: absolute;
  left: 32%;
  top: 28%;
  font-size: 3vw;
}

引用のところ

 以下のサイト様を参考にデザインしました。positionを少しいじったくらいでほぼそのままです。

o-ands.net

レスポンシブ対応

 雪のところでも書きましたが、今回はレスポンシブ対応を意識して書きました。

 Media Queriesなどは使わず、ひたすら%で指定していきます。次のようなプロパティです。

 margin、padding、widthなどはよく使いますが、font-sizeにvwを指定したり、topやleftに%を指定したことはなかったので勉強になりました。

印刷

 あまり技術的な話ではないのですが、画像はFirefoxスクリーンショット機能で撮影しました。

 f:id:dexia2:20161214214935j:plain:w300

 F12を押して開発者機能を表示した後、レスポンシブデザインモードのアイコンをクリックします。
 そうすると、小さなデバイス用の表示になるので、はがきサイズくらいに合わせてカメラのアイコンを押すとイメージファイルが取得できました。

 それをPDFに変換してUSBに移し、セブンイレブンで印刷しました。(印刷と年賀状の購入は別でした)

感想

 普段は業務システム担当なので、初めてデザイン的なCSSを使えて楽しかったです。

 やはり、遊びながら学ぶということが大事だと思いますね。

 実際に人に送るときは下のサイトを参考に動的にCSSで雪を振らせて、全員に微妙に違う年賀状を送れると素敵ですね。

qiita.com

 メッセージカードは大好きなので、また何かできたらいいなと思います。

パフォーマンス改善の時に考えること(プログラムレベル)

パフォーマンス改善について

 最近作成しているシステムはデータを扱うケースが多く、処理を書くたびにパフォーマンスが問題になっています。扱うデータが10万を超えて、全てインメモリという条件がついているのでなかなか厳しいです。

 今回はこのパフォーマンス改善についてとり組んできたことについて書きます。

 パフォーマンス改善には、レスポンス改善とメモリ改善の両方があります。今回はどちらも取り組んだのでその成果について書きます。

 ただし、今回はプログラムレベルできる改善にとどめます。今回は既存DBも扱うシステムで、DB周りはいじれませんでした。

両方に共通すること

  • 目標を決める
  • 計測する
  • テストをする

目標を決める

 一番重要なことはここまでのパフォーマンスは必要というラインを決めることだと思います。それによって取れる対策が変わってきます。

 本当に一瞬で返すことが必須要件といわれるとアーキテクチャをある程度壊さないといけないですが、数秒程度でOKならそこまでしたくはないです。

 あとは、画面によって求められる速度は違います。よく使う画面ほど速度が大事なので、そこらへんの見極めもありますね。

なんにせよ、目標がなければパフォーマンス改善はできません。

 また、環境条件もきちんと決めておいたほうがいいと思いますね。
 使えるメモリの量、ネットワークの速度を考えなかった場合、結果が異なることがあります。

 そして、環境のほうを改善してもらえるのなら、できる限りプログラムは触らないほうがいいと思います。技術的負債よりも環境を変えるほうが安いです。

計測する

 ボトルネックとなっている箇所を見極めることは大事です。
 アーキテクチャの大きな変更を伴う場合はある程度決め打ちすることもありますが、大体は計測してボトルネックだけを治して最小限の変更でとどめたいです。

print文で計測することもありますが、最近はVS2015に「パフォーマンスプロファイラー」という機能があるのでそちらを優先的に使っています。

 やはり、本気で作業する場合は手動よりも機械的な方法に頼るほうがいいですね。

テストをする

 当たり前ですが、パフォーマンス改善で機能を変えてはだめです。

 といっても大きなアーキテクチャの変更を伴う場合はこれが一番難しいです。

 テストスイートでもあればいいのですが、今回はなかったのでDBの最終結果をSQLで比較していました。

 とにかく小さな修正をするたびにテストしたほうがいいと思います。

レスポンス改善

  • ループ回数を減らす。
  • インメモリにする
  • 非同期にする。

ループ回数を減らす。

 10万件のループになると、それだけで遅いです。仮に処理が簡単であっても一気にボトルネックになります。

SQLで何とかする

 ではどうするのかというと、まずはSQLでなんとかできないかを考えます。

 ビジネスロジックSQLに持ちこむべきではないとは思いますが、パフォーマンスの観点からいえばできる限りDBサーバーに働いてもらったほうが効率がいいです。

 特に取得・集約処理を1回のSQLでできるようにすれば、大分早くなるのでこれをまず検討します。特に階層系のSQLをまとめると大きな改善になります。

 以前、Join禁止というプロジェクトがありましたが、検索のレスポンスが1分とか5分とかでした。やはり、SQLを最大限に使わずパフォーマンスを出すのは難しい面があります。

 また、自分たちの使っているDBはOracleですが、一括でSQLを発行するBulk機能があります。これを使うと何万件の命令をすぐにこなせたのでなかなか良かったです。

参照関係をきちんともつ

 今回のシステムではあるコレクションとあるコレクションをキーでぶつけて、処理をするということを何度もやっていました。もちろん、ループで。

こういうキーでぶつけれるときは、データ構造に参照関係をもつとループが減ります。

どうしても、データ構造を変えれないときはLinqのJoinなどで乗り切ってもいいと思います。

インメモリにする

 特にIOがネックになっている時は、インメモリで処理します。

データベースはうまく仕事を任せると早いですが、回数が多いと逆に最大のボトルネックになります。

 見極めは難しいですが、難しいビジネスロジックが入ってくる場合はインメモリで処理すると早いです。

 うちでは些細なことですが更新日付やマスタ値をとってくるところを数1000回ループして、遅くなることがありますね。

こういうDBアクセスはとりあえずメモリに入れてしまうという手があります。

メモリ使用量との兼ね合いもありますけどね。

非同期にする

 最近はLinqのAsParallelやTaskがあるので非同期のハードルは低いです。
処理の順番に制約がなく、メイン処理に関係ないところでは非同期でやってしまうという手があります。

 ただ、個人的にはバグになりやすい部分もあるのでできる限り最終手段にしています。
 最初からそういうデータ構造にしておくのならいいのですが。

メモリ改善

  • 都度処理を行う
  • データ型を変える

 都度処理を行う

 例えば普段かくプログラムはいったんDBから読んだレコードをリストに入れて、リストに対して処理するように書きます。

 ただ、あまりにもレコードが多いときは1件ずつ読みながら、その都度処理をしてクラスに持たないようにします。  

 実際問題、これができるケースは多くはないです。

またデータを極力DBに入れて、必要な時に必要な分だけとってくるようにします。

とくに表示するためのデータなどはインメモリで持たないようにします。レスポンス的には遅くなるので難しいですが、兼ね合いで決めます。

データ型を変える

 最終手段的なところはありますが、数字を扱う型をdecimalからdoubleやintに変えると何10%かは軽くなったと思います。  

 規約とシステムにもよりますが、数値の型はメモリに影響が大きいようです。

 まとめ

 今回行った対策はこのような感じです。10万件扱えるアーキテクチャと数千件のデータを扱うアーキテクチャの違いが分からず、結構苦戦しています。

 .NETのネイティブ周りや独自仕様(Formaアプリケーション)に詳しくないも原因かなと思います。

 そこらへんにもいずれ踏み込んで勉強したいです。

C#プログラマのための.NETアプリケーション最適化技法 (Programmer's SELECTION)
Sasha Goldshtein Dima Zurbalev Ido Flatow サシャ・ゴルドシュタイン ディマ・ズルバレフ イド・フラトー
翔泳社
売り上げランキング: 335,413

作業と順番

背景

 業務であっても、趣味であってもプログラミングをしていると、当然コーディングをして終わりということはありません。

 大抵、コードをリファクタリングする作業が必要ですし、場合によってはパフォーマンス改善(メモリの使用量削減、レスポンス改善等)に取り組むことがあります。

 今回考えたいのは、どの作業にどのタイミングでとり組むべきなのかというところです。

 自分はとりあえず動くコードを作る>リファクタリングですべての機能を作りこむことが多いのですが、最近はそうしないほうがいいのかなと思い始めてきました。

機能を作りこむ>リファクタリング>パフォーマンス改善

 自分はまず動くコードを作ることが多いです。

 多分、テスト駆動開発(TDD:Test Driven Development)に影響を受けていて、まずは動くコードを作って徐々に作りこんでいくのが好きです。

 こうすると純粋にロジックに集中できるので効率的に開発できる気がします。そこからリファクタリングをしてとりあえず作業は終了して、全部の機能を作りこみます。
 そして、ボトルネックになっている箇所があれば、パフォーマンス改善にとり組むという具合です。

 機能が一番重要で、パフォーマンスは後回しという考え方が背景にあります。

パフォーマンス改善>機能を作りこむ>リファクタリング

 逆にチームのメンバーは最初からパフォーマンス改善を考慮して設計します。

 そのうえで、機能を作りこんでいって、最後にリファクタリングをします。

 この順番で行くと納期が押していくと最終的にリファクタリングを切り捨てることになります。

 逆にメリットとしてはアーキテクチャの変更が最小限で済むということがあります。

 パフォーマンスを改善するときは大きなアーキテクチャの変更が必要なことが多いので、先に配慮しておくと修正が最小限で済みます。

個人的な結論

 これまで先にパフォーマンス改善をするやり方は「過剰な最適化」「早まった最適化」の類だと思って避けていました。

 ただ、現在の業務ではほぼすべてのケースでパフォーマンス改善の要求があって、逆にリファクタリングの効果が下がっていきます。

 それに会社全体としてリファクタリング自体が評価されない傾向にあるので(そもそもコードレビューもない)、他のメンバーに合わせるのがいいのかなと思うようになりました。

 もちろん、データ構造を大きく変えるとか、データ型を変えるとかそういった最適化は最終手段にしたいですが、アーキテクチャレベルの設計判断は早めのほうが自分の状況ではいいのかなという感じです。

趣味

 では、趣味はどうすべきなのかなと考えると、やはり同じなのかなと思います。

 趣味で何かを作っているとどうしても動くコードを作ることに腐心しがちなので、開発環境、パフォーマンス改善、リファクタリングその他もろもろが後回しになります。

 だから、コードを書くということの優先順位を少し下げて、学びに集中するくらいが自分にとってちょうどいいのかなと思います。