How IT Works

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

生産性を高める習慣

生産性を高めるもの

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

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

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

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

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

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

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

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

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

焦っていることに気付く

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

 そういうときはとにかく落ち着くことです。パニックになるときは大抵同時に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)に影響を受けていて、まずは動くコードを作って徐々に作りこんでいくのが好きです。

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

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

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

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

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

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

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

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

個人的な結論

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

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

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

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

趣味

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

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

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

はじめまして

あいさつ

 初めまして。dexia2と申します。地方でプログラマーをやっています。
 今日からブログを始めようと思います。よろしくお願いします。

自己紹介

技術スタック

 IT業界に入ってからは3年目くらいです。

  • .NETを使ったデスクトップアプリケーション開発
  • .NETを使ったWeb開発(ASP.NET+Single Page Application)

 あたりが専門です。
 今入社した会社はプログラム言語(VB.NETC#)、OS、サーバー、グループウェアの全部がWindowsなので技術スタックは基本的にそっち方向に偏っています。

 その反動でLAMPとか、Macとか、RubyPythonとかに憧れています。
 浮世離れしてないといいなぁ。

趣味

  • ヨーガ
  • バドミントン
  • クラフト集め(全部人にあげてしまいますが……)

 多分システム化できないことが好きなんだと思います。直観的にいい悪いとか感じられるところとかすごくいいです。  

 でも、ここらへんの分野とITをつないでいけたらいいなと思っています。

 ちなみに、ヨーガに関してはこんなものもあるみたいですが。

 あと、バドミントンもブログを持っています。しばらく更新しないですが、バドミントン好きな方はどうぞ。

ブログについて

始めようと思った理由

 普段冷静に自分を見つめる機会というのがなくて、それで学習機会を逸しているような気がしています。
 それでブログを書くことで自分のことを考える機会を増やせたらいいかなと思っています。

書きたいこと

 技術的にはあまり新しいことをしていないので、あまり書けないんじゃないかなと思います。

 どちらかというと人間的なところ、集中力の出し方とか思考の使い方とかハック的なところについて興味があるので、そこらへんについて書きたいです。

 まぁ、どうなるかはわかりません。趣味については仕事に関係ありそうなら書きます。

更新頻度

 自省の意味もあってできる限り書いていきたいですが、プログラミングや趣味との兼ね合いもあるので、不定期ということにします。

 目標としては週に1回くらい簡単にかけたらいいなというところを目指します。

まとめ

とりあえず、技術者として発信をしたことがないので、何か一つでも有益な情報を書けたらいいなと思います。