2018初夏、Visual Studio Codeに夢中

エディタなんて好きなものを使えばいいと思うし、他人に押し付けるものでもないし、なんなら自分はIDE派でもあるんだけど、最近Visual Studio Codevscode)を気に入って使っている、という話。

Microsoftの印象

自分にとってMicrosoftといえば悪いイメージしかなかったんだけど、最近はむしろ頑張ってるイメージが強い。なんなら軽く応援している。
きっとその要因の一つはvscodeだと思う。

vscodeがいい感じ

自分は最近少しだけGo言語を書いている。
Go言語を書いている人はvscodeを使っている人が多いと思う(超主観)。もちろん公式にはvimとかGoLandとかも紹介されているけど、自分はvscodeを気に入って使っている。

少し前までは色々なエディタを試してはしっくりこないくて乗り換える、というのを何年か繰り返していたけど、これをきっかけにvscodeでもういいか、という気になった。

コミット量

vscodeと他のエディタのコミット量をみるとこんな感じ。
vscodeが出て以降atomの開発が緩やかになった感じがする。
だからvscodeがいいんだ、という事ではもちろんないんだけど最近atomが元気ない感じがする。

atom/atom

f:id:y_d:20180518071802p:plain

adobe/brackets ※個人的に昔結構好きだった

f:id:y_d:20180518075820p:plain

Microsoft/vscode

f:id:y_d:20180518071757p:plain

↓雑に重ねるとこんな感じ(赤がvscode、青がbrackets

f:id:y_d:20180518075826p:plain

気に入らないところ

vscodeに対して不満に思っている箇所も多くあるけど、一番の不満は見た目がイマイチなところ。
アプリのアイコンだったり左側バーに並んだアイコン、隙間なくびっちり詰まったファイルエクスプローラーだったり。もうちょっとどうにかしてほしい。
※テーマを入れると配色やファイルアイコンの変更はできるけど



以上vscodeの見た目をどうにかして欲しいという話でした

golangでKVSサーバーを実装してみた

golangの勉強がてらKVSのDBサーバーを雑に実装してみた。
DBの実装自体はbuntdbというライブラリをそのまま使っているので、あまり大した事はやっていないけど。

実装したDBサーバーについて

  1. OrenoDBという名付けた(メンテするつもりはないので雑な命名)
  2. メモリベースのkey-valueストア
  3. ポート8888固定でtcp接続を待ち受ける
  4. redisプロトコルを採用したので一般的なRedisクラアントライブラリで接続できる

github.com

全体構成

大体こんな感じで実装されている。

  1. DBサーバーを起動して8888ポートで待ち受ける。
  2. clientが8888に接続しにくる。
  3. DBサーバーはclientを受け入れてgoroutineを起動する。
  4. groutineではclientからデータが送信されてくるのを待ち受ける。
  5. clientから送られた文字列を溜め込んで、コマンドとして解釈可能なレベルまで文字列が溜まるのを待つ。
  6. コマンドとして解釈可能なら、それを使ってDBエンジンにデータをRead/Writeしに行く。

f:id:y_d:20180418005307p:plain

その他

  • 軽く試した感じRedisよりもRead/Writeが速かった。これはBuntDBがredisよりも速い実装だから当たり前だけど。※index貼っていないので貼るともっと速くなるかも。
  • goroutineとchannelをうまく使いこなせていないのでgoroutineがリークしてるかもしれないのと、適当な実装がたくさんある。

PHPでbtree

f:id:y_d:20180306230107p:plain

golangで書かれた google/btree をPHP7.1に移植してみた。
移植する事が目的ではなく google/btree のソースリーディングだったので、かなり雑な移植になっている。

github.com

ソースの移植 golang --> PHP

golangをPHP7.1に書き換えた訳だけど、配列周りでクラス定義の工夫が必要だったものの、ほぼそのまま書き換えるだけで済んだと思う。メソッドの中身を見ると分かるけどgolangPHPはほぼ同じ行数になっていて、1対1でプログラムを書き換える事ができた。

golang

func (n *node) get(key Item) Item {
    i, found := n.items.find(key)
    if found {
        return n.items[i]
    } else if len(n.children) > 0 {
        return n.children[i].get(key)
    }
    return nil
}

PHP

<?php
public function get(Item $key) : ?Item
{
    list($i, $found) = $this->items->find($key);
    if($found){
        return $this->items[$i];
    }else if($this->children->count() > 0){
        return $this->children[$i]->get($key);
    }
    return null;
}

またgolangでは下記のように組み込み型にエイリアスやメソッド追加ができるため、PHPへの書き換えが難しく悩んだ箇所だった。PHPと比較して、golangにはこういうパフォーマンスに配慮した機能があるのが特徴的だなぁ、と書き換えながら感じた。

type Int int

// Less returns true if int(a) < int(b).
func (a Int) Less(b Item) bool {
    return a < b.(Int)
}

パフォーマンス

せっかくなのでパフォーマンス比較をしておこうと思う。
そもそも実用目的に移植した訳ではないのでパフォーマンスや可読性などは気にもしていなかった訳で、PHP版は1レコードあたり1インスタンスを生成する作りになっていたりと、パフォーマンスがでるはずはないのだけれど。

以下の通りbtreeにデータを流し込んだ時の速度を比較した。検索速度は比較するのが面倒なのでしていない。

golang(10万件データを投入)

$ time go run btree_mem.go --size=100000
   ....省略...
real    0m0.311s
user    0m0.301s
sys 0m0.118s

PHP(10万件データを投入)

$ time php btree_mem.php
   ....省略...
real    0m6.016s
user    0m5.851s
sys 0m0.145s

上記の通り処理時間も google/btree の圧勝だったし(0.3秒:6秒)、google/btree の方が圧倒的に省メモリだった。
※100万件の投入でも google/btree は数秒で終わったが、PHP版は数分間待っても戻ってこなかったので強制終了した

一応念押ししておくと、決してPHP言語そのもののパフォーマンスが悪いとか、golangが優れているとか、そういう事を言いたい訳ではない。
パフォーマンスがでないのはソースが悪いという事とと、そもそもこうした比較をする事が間違っていると思っている。※じゃあ比較すんなよ的な