普段使いのブラウザ比較

これまでChromeを使っていて大きな不満があったわけではなかったが、少し気になるところがあったので他のブラウザを試してみることにした。

PC環境は Mac OS X Yosemite, Macbook Pro 13inch Late 2013 (2.6 GHz Intel Core i5, 16 GB Memory)

まとめ

  • 体感での速度はほとんど差がない
  • メモリ使用量もほぼ同じ
  • 機能拡張やUIの好みに合わせて決めるのが良い
  • 個別の環境で特に何か大きな問題が起きていない限りは、ブラウザを変えることの手間のほうが高い。

Chrome

通知ダイアログ

Gmailやチャットをブラウザで使っているので通知をONにしてみたところ、デザインがMacのNotificationとあっていない。 Material designはGoogleの他のプロダクトとは統一がとれているのかもしれないがMacだと浮くと思う。 これは好みの部分が大きいが、見るたびに気になるので止めてしまった。

メモリ使用量

普段使っているページ (Gmail, Google Docs, Google Calendar, Asana) その他いくつかのタブを開いて、機能拡張を5,6個入れた状態で1GBを超えるくらい。過去にアクティビティモニタで見たときにブラウザで1GBも使うのかと思ったが、今回比較してみてそうでもないことがわかった。

その他

Flashが内蔵されているので、OS側にインストールしたりアップデートの管理をする必要がない。地味に便利。

Firefox

概ねChromeと同じような操作感。もしChromeからの代替ブラウザを探しているならSafariよりこちらのほうが良いかも。

メモリ使用量

起動時は確かに少ないが、重いページを開けばそれなりに食う。上のChromeと同じページを表示すると1.2GBくらい。

その他

ページ内検索は/キーを押すと検索が始まり、インクリメンタルサーチができる。これは昔からあったが便利。 ちなみに、最近Webページ側で検索用のショートカットに/を割り当てているケースがあるのでどうなるかと試してみたところ、Webページのほうが優先される模様。

タブ固定した時に、各ページに更新があったかどうかがハイライトされ見やすい。Chromeでも同様のものがあるがこちらはハイライト加減が微妙なので少しわかりづらい。

Safari

速度

他と比べて若干速いかな、という印象。スクロールなどの引っ掛かりが少ない気がする。大きく変わるほどではない。

メモリ使用量

他と変わらず

ショートカットキー

ショートカットはキーの割り当てが独特で、一部のキーが使いづらい。具体的には、

  • 閉じたタブを戻す時に、他ブラウザでは コマンド+Shift+T だが、Safariだとコマンド+Z (通常のアンドゥと同じ)。テキスト編集などでアンドゥをした時に誤ってタブが復元されたり、タブを復元したいのにアンドゥされたりと操作にバッティングが起きる。
  • タブ移動は他ブラウザではコマンド+1-9だがSafariではその方法がない。コマンド+1-9はお気に入りのページを開く操作に割り当てられているので、間違って開いたりする。

ジェスチャー

トラックパッドでのジェスチャーサポートが豊富で、かつアニメーションが自然。 例えば、2本指スワイプでページを戻る際にはっきりとアニメーションするのでわかりやすい。Chromeだと左右スクロールしているだけのつもりが戻ってしまったりしていた。 またピンチインしてでるタブ一覧も良い。ただキーボード主体で操作する人間としては、こちらはあまり使わないかも。

タブ固定

あと、タブ固定が出来ない。さらにFaviconもでないのでどのタブがなんなのか直感的にわからない。 (FaviconSIMBLか何かの拡張でできるらしいがそこまでするほどでもない)

その他

タイトルバーが他と比べて上下に狭くなっていて、縦幅が貴重な最近のディスプレイ事情を考えると少しだけ有利。気にするほどではない。

URLバーで検索すると検索ページに飛ぶ (おそらくデフォルトはGoogle) が、飛んだ後にURLバーにフォーカスが当たったままになる。他ブラウザではフォーカスがページ側に行くので違和感がある。Tabを押せばフォーカスが映るがそれもイマイチ。(ただ、その状態でも地味にCtrl+N/Pでページの上下移動ができたりする)

ローカルファイルでのproxy.pacによるプロキシ設定が効かない。どうもSandbox化による影響とのこと。

http://qiita.com/tkyk@github/items/5824539d0841dee254bc

結果

気分を変えたいこともあってSafariをメインにした。ただ、タブ固定して表示しておきたいページがいくつかあるのでそれらはFirefoxで使っている。Chromeは使っていない。結局2ブラウザ使うことになって便利になったのかどうなのか微妙なところ。

Chromeは使いやすくカスタマイズしていたので戻るかもしれない。

追記 (2015/06/01)

しばらくSafariオンリーでメインに使うことにしたので、いくつか使いやすくする拡張を入れることにした。

1時間以内に解けなければプログラマ失格となってしまう5つの問題

ちょっと時間があったので試しに解いてみると、想像以上に良い問題だった。

http://www.softantenna.com/wp/software/5-programming-problems/

Rubyだと解くまでもない問題があるので、なるべくRubyっぽくなく解こうと思ったが、最後の方はやはりRubyっぽさが出てしまった。

だいたい45分。まあ、こんなもんか。 問題5は時間を気にしすぎで8重ループで解こうとしてみたり。いかんいかん。

こういう問題は勉強中の言語で解くと参考になることが多い。以下も含めてGoでやり直してみたい。

言語処理100本ノック 2015

人工知能は人間を超えるか

ディープラーニングについて概要を知るために購入。これまでニューラルネットワークのすごいものくらいに理解していたディープラーニングの概要がつかめる良い本だと思う。また、ディープラーニングだけでなく人工知能の経緯など書かれているので、この分野に疎い自分には参考になる。

機械学習については少し学んだので前半部分はさらっと読んだ感じ。ディープラーニングの部分からはしっかり読んだ。最終章はタイトルにもあるように未来のAIと人間との関係を考えるところ。ここは各人色々な思いがありそう。全般的に機械学習や数学のバックグラウンドが無くても分かるように説明されているので、なんとなく最近の人工知能のことを知りたい人にもお勧めできる。

この本の中で分かったディープラーニングの特徴は以下。

  • それまで人間が与えていた特徴量も自動的に学習できるようになった
  • 自己符号化器による学習ができるため、教師あり学習はごくわずかで良い
  • 学習手法に工夫を凝らすことで頑健である
  • 学習にかかる計算量が大きい (Googleの例では1000台のサーバを使って数日など)

グーグルの猫認識の例^googleにあるように、特にモデリングなしでも学習によって猫や人間の顔らしき概念を学ぶことができるため、人間は出来上がった概念に猫というラベルをつければ良い。これは逆に言えば、人間の知らない新たな概念をコンピューターが発見して、それに人間がラベルをつけるということも考えられる。(このあたりのことはTEDでも似たような概念図を見た気がする^ted)

この本の前にファストアンドスロー (リンク下部) を読んだが、人工知能の壁の一つとしては、人間にとってのシステム1 (直観的な判断を下すシステム) かもしれない。論理で構成するものではなく、おそらく人間の進化の過程で脳に組み込まれたこのシステムは、かなりの学習をしても機械と人間を隔てるものになる可能性がある。逆にシステム1のない機械の方が、(システム1をOFFにできない)人間よりも発展を遂げるかもしれない。

あとがきにある著者の松尾さんの人工知能にかける思いは、とつとつとした文章ながらも熱いものが伝わってくる。

ファスト&スロー (上)

ファスト&スロー (上)

深読みしないRuby Refinements

ruby 2.1からの Refinements を使ってみようとして、思い通り通りに動かないことが多かったので、まとめた資料です。 仕様をまとめたものはRefinementsSpecにあるのですが、そこまで読まずに簡単に試してみたい場合にポイントとなるところをまとめます。

基本的な使い方

例として文字列のサイズを偽るRefinementsを使います。 これ以降の例でもusing Aが出てきますが、同じモジュールです。

Stringの長さが-1になっていれば、このRefinementsの影響を受けています。

module A
  refine String do
    def size
      -1
    end
  end
end

using A
'hoge'.size                     # => -1

usingを使うと、それ以降のスコープでリファインしたメソッドの挙動が変わります。

クラスやモジュールでスコープを切ることもできます。便利ですね。

class B
  using A
  def hoge
    'hoge'.size
  end
end

B.new.hoge                      # => -1
'hoge'.size                     # => 4

スコープについて

usingを使うとそれ以降の処理に影響します。

以下の例では、usingを使う前後で結果が変わっています。

'hoge'.size                     # => 4
using A
'hoge'.size                     # => -1

using以降のクラス定義も影響を受けます。 以下の例ではClass B内ではusingを仕様していないにもかかわらず影響を受けます。 場合によっては、あまり想定しない影響を起こすかもしれません。

using A

class B
  def hoge
    'hoge'.size
  end
end

B.new.hoge                      # => -1
'hoge'.size                     # => -1

モジュール内のクラス全てにリファインメントを影響させることもできます。 こちらは通常意図する使い方になると思います。

module D
  using A
  class B; end

  class C
    def fuga
      'fuga'.size
    end
  end
end

D::C.new.fuga                   # => -1

スコープについて2

クラス定義内でも順序を入れ替えるとusing前のメソッド定義は影響を受けません。 この例ではメソッド定義後にusingを使っているため、上書きされません。

# Bad example
class B
  def hoge
    'hoge'.size
  end
  using A
end

B.new.hoge                      # => 4

ややこしくなるので、通常は先頭でusingを呼ぶ方が良さそうです。

以下の例では、後からRefinementsの影響を入れるために、クラスを再オープンしてusingを使用しています。 しかし、元のクラスで定義されたメソッドはRefinementsの影響を受けませんので、この使い方は無意味です。

# This does NOT work
class B
  def hoge
    'hoge'.size
  end
end

class B
  using A
end

B.new.hoge                      # => 4

直接usingした範囲でしか影響しない

ここははまりどころだと思いますが、 Refinements の影響を受けるのは直接usingを使用されたクラスのみです。 そのクラスから呼ばれていても、別のクラスのメソッドを経由した場合は、元のメソッドが呼ばれます。

ややこしいのでサンプルで説明します。

class B
  def hoge
    'hoge'.size
  end
end

class C
  using A
  def fuga
    B.new.hoge
  end
end

C.new.fuga                      # => 4

class Cusingを使用しています。しかし実際にString#sizeを呼ぶのはclass Bです。 そのためclass Cでのusingの影響は受けず、元の長さを返します。 class Cでのusing Aで文字列の長さを変えたいと意図していますが、そのようには動作しません。

さらに別の例があります。こちらもはまりやすいパターンです。

class String
  def my_size
    size
  end
end

class B
  using A
  def hoge
    'hoge'.my_size
  end
end

B.new.hoge                      # => 4

Stringに別のメソッドmy_sizeを定義して、その中でsizeを呼んでいます。 my_sizeusingしたBから呼ばれるので、一見上書きしたsizeが呼ばれそうですが、String#my_sizeには影響していないので、呼ばれるのは元のsizeです。

まとめ

Refinementsはあくまでそのクラスから見たメソッドの見え方を変えるもので、他のクラスには一切影響しません。たとえメソッド呼び出しの契機となるクラスでusingを使っていても、他のクラスを経由した場合の動作は変わりません。*1

モンキーパッチとして使う場合、表側に近いクラスの挙動は変更しやすいですが、奥の方にあるクラス(内部向けのクラスなど)や多数のクラスから呼ばれるメソッドの挙動を変えるには工夫が必要そうです。

「限定されたスコープで動作する」というところがRefinmentsのポイントなので、スコープが不足していると思ったら、別の方法も検討しましょう。

*1:わかりやすくクラスと書いてますが、もちろん使い方によってはクラスだけではないです

ちょっと便利なキーバインド2

先日のポストに続いて、新たに覚えたものを追加。

ちょっと便利なキーバインド - ikeas's blog

C-x C-o (delete-blank-lines)

カーソルより下の空行を削除する

M-^ (delete-indentation)

上の行と連結する。 下の行と連結する(VimでいうJ)場合は、C-u -1 M-^ とかでできるがちょっとタイプ数多い。。

M-q (fill-paragraph)

ページ幅が埋まるように自動的に改行を調整する。 長い分を折り返したり、逆に短い行を一つにまとめたりすることができる。 途中に重複する空白がある場合は、空白も一つにまとめられる。 コメントなども考慮してくれるので、コメント部分を編集した後、規定の幅文字数以内に収めるような使い方もできる (わざわざ手でコメント記号を考慮しながらカットペーストする必要がない)。

C-x z (repeat)

直前に実行したコマンドをリピートする (文字入力は無視した直前のコマンド)。 C-nなどのカーソル移動も対象となるので、それに奪われやすい。次のC-x ESC ESCが便利かも。

C-x ESC ESC (repeat-complex-command)

直前に実行したミニバッファを使用するコマンドを再実行する。 query-replaceを間違って途中で止めてしまった場合などに再実行するのに便利。

コマンドを入れるとミニバッファに内容が出てくるのでRETを押すと再実行できる。 ここで M-n / M-p を押せば履歴を移動できるので少し前のコマンドも実行し直すことができる。 (M-n / M-p はミニバッファ共通のヒストリーコマンド)

M-(数字)

C-u (数字) と同じ

C-u (数字) C-u (数字)

数字を繰り返し入力したい場合には C-u を途中に挟む。 例えば 0 を10個入力したい場合は、C-u 1 0 C-u 0 と入力する。 ハイフンの場合も同様。M-(数字) の時も使える。

マクロ

あまり使いこなしてないがマクロの簡単な使い方

C-x ( でマクロ開始。 繰り返したい操作を入力。 C-x ) でマクロ終了。 C-x e でマクロ実行。

read-only-directory 特定のディレクトリ以下をread-only-modeで開く

Githubにあるソースなどを読むためだけにEmacsで開くとき、思わず編集したりしないように (auto-save-modeを使っていることもあり) read-only-modeに切り替るのだが、多数のファイルからなるレポジトリの場合、バッファごとに都度切り替えるのが結構手間である。

そこで、特定ディレクトリ以下にある場合は、ファイルオープン時に自動的に read-only-mode にするようにした。

read-only-directory.el

elispをload-pathに配置した後、以下の設定で読み込む。

(require 'read-only-directory)
(read-only-directory-init)

最初は対象ディレクトリリストは空なので、対象にしたいファイルを開いた状態で、M-x read-only-directoryでリストに追加される。 また、(read-only-directory "/path/to/dir") でも追加できるので、例えば以下のようにprojectileと組み合わせて、現在のレポジトリのルートパスを追加するようにできる。(プロジェクトでない場合はデフォルトの動作でカレントディレクトリを追加する)

(defun my-read-only-directory ()
  (interactive)
  (read-only-mode t)
  (read-only-directory (when (projectile-project-p)
                         (projectile-project-root))))

まだ最低限使える機能しか実装していないので、リストから削除するには (read-only-directory-del "/path/to/dir") を評価するか、直接セーブフィル (デフォルトでは ~/.emacs.d/read-only-directories)を編集してから (read-only-directory-load) をscratchバッファで評価する。

セーブ、ロードあたりは bm.el の実装を参考にさせてもらった。

joodland/bm · GitHub

ちょっと便利なキーバインド

これまでEmacsを使っていて気づかなかったものの、改めて見てみると便利そうなキーバインド。 (Emacs 24.4なのでバージョンが古いと違うかもしれない)

M-h (mark-paragraph)

現在のパラグラフを選択する。 パラグラフは概ね前後の空行までの範囲。(モードによって変わると思う) カーソル移動するだけなら、M-{, M-} が対応する。

C-S-Backspace (Ctrl + Shift + Backspace) (kill-whole-line)

現在カーソルのある行をkill ringに入れる。C-a C-k C-k を押すのと同じ

s-u (revert-buffer)

Super + U あまり使われないSuperキーを使う。Macだとデフォルトはコマンドキー。 M-x revert-bufferをよく使う人はぜひ。

s-k (kill-this-buffer)

Superキーシリーズ。C-x k (kill-buffer)とは異なり、ミニバッファで確認せずにカレントバッファを閉じる。

その他

使いこなすと便利そうだが覚えるのが無理そうな移動系。M-a/eは押しやすいので使ってみてもいいかも。

  • M-a, M-e (backward-sentence, forward-sentence)
  • C-M-a, C-M-e (beggining-of-defun, end-of-defun)
  • C-M-f, C-M-b (backward-sexp, forward-sexp)
  • C-M-n, C-M-p (forward-list, backward-list)