わざと雑に作る

f:id:onody_onody:20150422180500j:plain

日本に暮らしていて、海外旅行に行くたびに、交通インフラの雑さに驚く。
ここ4日間行っていたサンフランシスコも結構雑だった。

バスを例に取ると、、

  • 基本時間通りにこないことがおおい。数分ずれたりは結構普通。
  • チケットは乗るときに見せたりするけど、期限切れていたり、老人用のパスとかを見せても余裕で乗れる。
  • 後方の入り口(運転手がチェックしない)からでも普通に乗れる。

日本だと、チケットを買って、しっかり機械でチェックしてOKにならんと乗れない。

こうなると、ちゃんとお金もらわないでやっていけるのか?とおもうけど、
一応まわっているみたい。

なんでかというと、たまに抜き打ちでバスに警察が乗ってきて
抜き打ちチェックする。
チェックでダメだと、罰金のペナルティーがある。

実際、その抜き打ちを受けているところを見たけど、
1〜5%位の人がひっかかってた。


ここで考えるべきは、
1. 99.9%お金を徴収するために、完全なシステム化するコスト(もしくは定刻発車にするコスト) 2. 95%お金を徴収するために、ざっくりシステム化するコスト(もしくはすこし遅れて発車にするコスト) である。

で、日本だと結構1のパターンで考えて行くことが多い。
2の方がトータルお得な場合でも、1となる場合が多い。

システム化するときも、無条件に1の思考パターンになってしまう人が多い気がする。


複雑な仕様を実現するために、
if,if,if!なプログラムを作っていることがおおい。
結果的に、ifばっかりだと、バグりやすくて結果コスト高になる(循環的複雑度が高い)のに!

コストを考えて雑に作るのは全然ありだとおもう。

つまり、この条件反射的な仕様の考え方は、
自分も結構しみついているので、
トレーニングしていきたいです。

なんで便利なツールがたくさんあるのに、口頭で情報共有をやっちゃうのか

facebookで流れてきた記事。

この記事の最後の部分にある「情報共有と効率化」について思うところがあったので書いてみる。

会議が多い会社はだめ、みたいなセリフをよく耳にする。

これは会議自体が多いのがだめなんじゃなくて、
会議で大事なのは、意志決定なのに、情報共有ばっかりになってんじゃないの?どうせ。
みたいな意味で言われることが多い。

記事で書いてある、「Google社内では仕事を人に聞くと怒られる」も
つまるところ、おまえせっかくインフラ作って情報共有していてやってんのに
何でおれの時間とって聞いてきてんの?うっぜー!効率わるーーー。
なんだとおもう。(想像)

じゃ、なぜ効率的な情報共有ツールが世の中にはたくさんあるのに
口頭で情報共有がなされるのか。
理由を考えてみた。

  • そもそも社内に、配布したい情報にあったコミュニケーションツールがなくて、
    そこを作るところからと考えると、面倒くさくなるから。
  • 社内にツールがあることを知らないから
  • 社内にツールがあるのに使いたくないから
    • 何となく口頭のほうが、共有されている感がある
    • ツールの使い方がよくわからない
    • 情報共有の優先順位よりも高い仕事に追われている
    • 社内でツールを使う人が少ないから、自分が利用しても読まれないのではないかと感じてしまうから

こんな所かな。

考えてみると、口頭での情報共有をしちゃう理由って
人間の心理的で情緒的なところの理由が多い。

よくいわれる、
ミスったときの謝罪はメールや電話で済ませるな!てきな話があるけど、
これもミス内容の情報共有自体はメールでやった方がよい。
事実がログとして残るし、文章として書くことで曖昧さが減る。

ダメなのは、ついでにその情報共有のメールとかに謝罪文とか
エモい内容まで書いてしまうこと。
基本ツールでエモを出すことは難しいので辞めた方が無難だとおもう。

ということで、社内ツールを使った情報共有については、
システム自体を整えても、
心理的なもの、情緒的なものがハードルとなっている人が必ず出てくるとおもうので
そういった人がハードルを越えられるよう
習慣化させるところまで面倒見てあげる必要があるんではないかと思います。

そりゃ、組織の全員が、効率的な情報共有の意識が
最初から根付いている集団であればよいが、
そんなものはなかなか無いんじゃないかと思う次第です。

Bitcoinの取引のしくみについてメモ

Bitcoinについて技術的に理解したいとおもって色々調べていたけど、
ブロックチェーンに関する詳細説明が多くて、
もう少し全体的な取引部分(トランザクション部分)の話が
まとまっているのがないかなと思って調べていたら
これがわかりやすかったです。

トランザクション部分のまとめ(解釈ふくむ)

  • まず、お金の送金についての登場人物を単純化すると、送る人(仮にAとする)と、もらう人(仮にBとする)の二人。

  • 銀行は、A・Bの財布を管理している、サーバ型。

  • Bitcoinは、集中管理サーバが無くて、それぞれが全部の取引記録をもっているP2P型。

  • 例、AからBへの1円の送金

  • 銀行:サーバでA-1、B+1すれば終わり。

  • Bitcoin:Aが、「A-1、B+1」したという情報を全ノード(ex: C.D.E....)に送信する。
    つまり、Aが送金したその時点では、財布からお金が減らない。Bに+1されたかどうかもわからない。
    これだと、Bに送金して、速攻、Cに送れるのではないかと思うが、
    AがCに送金をしようとしても、他のノードは、Bに送金したことを知っているので、不正とみなされる。

  • 「A-1、B+1」されたという情報をA自身が知るのは、
    10分ごとに送られてくる全ユーザの取引情報のアップデート(ブロックチェーン)を受け取ったとき。

流行るかどうか、など色々な考察はおいておいて、
仕組みだけ見ると、無駄な通信が大そうだとは感じる。

ひろゆき氏が言っていたように、P2Pは、
「ビール1杯目無料の居酒屋で、客がみんな1杯しか飲まずにみんな返ったら破綻するシステム。」
な気はする。基本的にスケールしづらいよね。
しようとすると、どんどん複雑な機能を足さないといけないし、足しても完璧ではない。

2015の目標(自分にストレスをかけてやらせる)

目標とかあんまし立てたことはないけど、
今年は気が向いたので書いてみる。

●●をつくる、とか自己啓発アウトプットおらおら系の目標は
たてても自分は一度も達成したことがないので書かない。
(自分にはむいていないようだ)

どちらかというと、自分で制限かけていって
ひねり出すかんじがいい感じになることが多い気がするのでそうしてみた。
いかんせんMなので。

パソコンを使う時間を減らす(20%カット)

10月〜12月のパソコン使用時間が700h。
そのうち、仕事じゃない、ネットでの暇つぶしやらなんやら60〜100h。

10〜20%くらいつかっている暇つぶしの時間を、
5%以下にしたいのと、
仕事自体もなるべくパソコンの前にいる時間を減らしたい。
計測に使っているソフトはこれ。

RescueTime : Time management software for staying productive and happy in the modern workplace

パソコンの前にいても、
あんまり自分のキャリアにプラスなってないなーとおもうことが多かったので、
ほかに時間を充てるようにさせたい(自分を)。

映画と本を読む時間を増やす(去年の倍)

去年はいろいろな事情でお金が使えず、
例年以上にひまなときはネットばっかしみてた。

ネットって終わりがない。
なので、自分で区切らない限り、終わらない。
自分は我慢できないので、楽しそうなバナーがあったら速攻クリックしてしまう。
気がついたら、ロシア人のコスプレイヤーのブログを一生懸命翻訳してたりする。
この2時間くらいの記憶がない。とかざら。

暇をつぶしながらも、
きちんと情報を整理して、自分に落とし込んでいる意識ではいたのだけど、
案外そうでもなかった。

ネットの方が、自分でコントロールしやすいので、
自分で考えている時間が多いと思い込んでいたけど、
意外とだめで、コンテンツが大量にあるので
さばくのに時間を使いすぎて、自分の中で練るところまでいけないことがおおい。

で、去年の終わりに、少しネットを絶って映画とか本とかにかえてみたのだけど、
思っていたよりいいかんじ。

  • 映画:月5本→10本
  • 本:月5冊→10冊

が目標。

目標の狙い?は、ひまでかつネットのできない時間をたくさん発生させて、
家ってつまんねーから外でていこうかな。
と自分をだますこと。

思った方向に転がるといいな。

AirMacにつないだBeagle Bone Blackに接続する時

久々にBeagleBoneBlack(以下BBB)をいじろうと思い、 無線ルーターに優先接続してみたものの、 sshでつなぐ方法を忘れてしまっていたので、再度ネットで調べながらやってみた。

まず、BBBのIPアドレスを調べるよ。

# 無線ルータに接続されてる機器のIPリスト
arp -a

IPがわかったらssh

ssh debian@〜

自分の場合は、ID/PWはdebianの初期設定のままだったので、 debian/temppwdでした。

何もいれていない場合は、root@〜でたしか入れたはず。

※おまけ 無線モジュールを導入

以下を参考に設定。

BeagleBone Blackの設定(OS非依存) | OpenRTM-aist

自分の場合は、無線モジュール(ドングル)を指しただけで 認識されたのでスムーズに行きました。

おしまい。

MySQLでindexをつけると、どのくらいSelectのスピードが変わるのか

仕事で良く使っているMySQLのクエリの実行速度について、 感覚として知っておきたかったので実験。

注)個人メモなので、オチとかないです。あらかじめ言っておきます。

  • MacbookPro 2.2Ghz コアi7 メモリ16GB
  • homebrewでインストールしただけのmysql
  • 10万件のユーザデータを1つのテーブルに格納。
  • シンプルに東京在住、20代、男性、のように3カラムのWHEREで絞る。
  • Rubyのbenchmarkモジュールを使って実行時間を計測。

データサンプル

こんな感じ。

f:id:onody_onody:20141103201332p:plain

RubyのFakerというgemでダミーデータは入れました。

まず普通に実行

Benchmark.bm do |x|
  x.report {
    # 検索結果が少ない順
    puts User.where(:state => '東京都', :age => 20..29, :sex => 1).count
  }
end

都道府県は、日本語で最初はやりました。

  • 結果
      user     system      total        real
  0.010000   0.000000   0.010000 (  0.046598)

indexをつけてみる。

MySQLには、indexという機能がある。

要は、普通に以下の様なクエリを投げると、

SELECT * FROM users WHERE 'state' = '東京' AND 'sex' = 1 ...

MySQLは最初にテーブル全件を読んで、そっから絞り込むので 件数が多くなるほど遅くなると。 それを解消するために本のさくいんのようなものをつけるのがindexだそうです。 以下参考。

今回は、state、age、sexに複合インデックスをつけてみたいと思います。

  • 結果
      user     system      total        real
  0.010000   0.010000   0.020000 (  0.018678)

半分以下になりました。

都道府県を数字にするとどの程度かわるか

さっきまでは、都道府県をVACHARでやっていたので それを数字に置き換えてINTEGERに変更してやっていました。

      user     system      total        real
  0.010000   0.000000   0.010000 (  0.017745)

あんまかわんないね。

結論

あたりまえですが、indexの効果は大きく、 今回のテストでは半分くらいの実行時間にまで 短縮することができました。

あとは、こういうことを実験しておくと、 体感として効果が実感できるので、 業務の時の判断にも生かせそう。

なのでまた色々ベンチマークやテストとかしていきたい。

最適化オプションを知った。

言語の処理速度に興味があったので、C言語Javaphpで同じ処理を行った場合の速度比較をやってみた。

処理内容は、以下サイトのコードとほぼ同じ。

TAKENAKA's Web Page: meshcode

C言語

#include <stdio.h>

int main(int argc, char *argv[]) {

    int rep = 1000000; // 足し算の回数
    int n   = 10000;   // 変数の数(配列の要素数)

    int x[10000] = {};

    for (int j = 0; j < rep; ++j) {    
        for (int i = 0; i < n; ++i) {   
            x[i] += 1; 
        }
    }

}

Java

package com.company;

import java.util.Arrays;

public class Main {

    public static void main(String[] args) {


        int rep = 1000000;
        int n   = 10000;

        int[] x = new int[n];
        Arrays.fill(x, 0);

        for (int j = 0; j < rep;) {

            for (int i = 0; i < n;) {
                x[i] += 1;
                i++;
            }

            j++;
        }


    }
}

PHP

<?php

$rep = 1000000;
$n   = 10000;

$x = range(0,$n);

for($j = 1; $j < $rep; $j++){

  for($i = 0; $i < $n-1; $i++){
    $x[$i] += $i;
  }

}

?>

結果

ざっくりと知りたかったので、 今回はtimeコマンドでやってみました。

C言語 Java PHP
real 0m26.795s 0m1.698s 9m54.769s
user 0m26.754s 0m2.134s 9m53.398s
sys 0m0.028s 0m0.217s 0m0.789s

様子がおかしい?

PHPは、そうなんだろうなという印象だったのだけど、 CとJavaが思ってたのと違う!!

CとJavaについては、まったくいじったこと無かったので、 よくわからないので、質問してみました。

c言語、javaの実行速度について、解決できない疑問があります。 … - 人力検索はてな

ご回答頂いた方によると、コンパイラの最適化が関連しているのでは?ということ。調べてみる。

最適化実行

C言語コンパイルするときは、自分のMac環境では以下の様に行っていました。

gcc main.c -o main.out

これを以下の様にオプションをつけると、 どうなるか。

gcc -O2 main.c -o main.out

再度計測!

C言語 (最適化前) C言語 (最適化後) Java PHP
real 0m26.795s 0m1.484s 0m1.698s 9m54.769s
user 0m26.754s 0m1.474s 0m2.134s 9m53.398s
sys 0m0.028s 0m0.006s 0m0.217s 0m0.789s

これだよ、求めていたのは!

最適化オプションをつけたとき、コンパイラは何をしているんだろう。

最適化については、コンパイラによって様々な最適化を行うらしいのだけど、 共通しているのは、コンパイルにコストをかけて、プログラム実行時のコストを減らすということみたい。

Using and Porting the GNU Compiler Collection (GCC) - GCCコマンド・オプション

今回のコードにおいては、最適化オプション指定時に変数へのアクセスが、メモリじゃなくて、CPUにあるレジスタにおきかわって、forとかでアクセスしまくっている変数がregister宣言に置き換わって、爆速になったのでは?と考えている。

最適化結果を知りたいと思って、逆アセンブラとかしてみたんだけど、 アセンブラが読めないことを忘れていて、撃沈。。

結論

自分のような、WEBのフロント側から、バックにきた人間にとっては、 C言語コンパイルの裏、レジスタのことなど、 当たり前だけど、知らないことが多いので、こうやって調べていくのは大変勉強になる。

普段phpのWEBアプリを作っていて、 たまに複雑な計算処理などが入るときも 力業でphpで書いて、夜間にバッチで処理なんてやってたけど、 ある部分、処理にあった言語で実装をしなおして 高速化や効率化を今後考えていきたい。

追い切れていないところ

※Goもやってみたので追加

package main

func main() {

    rep := 1000000
    n := 10000

    var x [10000]int

    for j := 0; j < rep; j++ { // rep 回の繰り返し
        for i := 0; i < n; i++ { // 一万個の変数それぞれに値を加える
            x[i]++
        }
    }

}
go build main.go
C言語 (最適化前) C言語 (最適化後) Java PHP Go
real 0m26.795s 0m1.484s 0m1.698s 9m54.769s 0m9.053s
user 0m26.754s 0m1.474s 0m2.134s 9m53.398s 0m9.049s
sys 0m0.028s 0m0.006s 0m0.217s 0m0.789s 0m0.008s