MBA+Lionキタァ

ようやくMacBook Airが届いたので、昨日はセットアップしました。
個人的には、きれいな状態から使いたいので、移行アシスタントなどのツールは使わず、設定していきました。

セットアップを一からするにしても、すごく便利になってますね。
MobileMeのアカウントを最初の起動時に入力すると色々設定してくれるのは前からですが、Safariで初めてGmailにログインしたときにSafariがMailとiCaliChatの設定する?と聞いてくるので、とりあえず全部設定してみた。
勝手にMail.appにGmailのアカウントが追加されて送受信できるようになり、iCalGoogle Calendarのデフォルトカレンダーが追加される。iChatにもアカウント追加されてた。
困ったのは、せっかくIMAP使っているのにローカルにメールをダウンロードする設定になっているので、Gmailの凄まじい量のメールをダウンロードしにいってしまうこと。ネットワーク接続していない状態で使うことは現在はあまり考えられないし、iPhoneでも確認できるのでローカルにはダウンロードしない設定に変更した。
それでもダウンロードが長かったのはGmail側の設定で、IMAPフォルダのメール数を制限なしにしていたからだったので、とりあえず2000件に変更することで、すぐに同期が終了しました。

Gmailをメインのメールに移行してからは、ほとんどメーラー系は使わなくなっていたのですが、iPhoneの使い勝手がよいので、ひさしぶりにメーラーを使ってみようかと思っています。OS X LionからはMail.appの操作が大きく変わり、以前より使いやすくなっています。

Scala Parallels Collections

この記事はScala Advent Calendar jp 2010 : ATNDの24日目です。

概要

Scala2.9ではParallel Collectionsが使えるようになります。
パソコンのCPUがコアいくつもあるんだからCollectionも並列処理したいですよね。
詳しくは、Index of /node/138/140を見ると良いでしょう。

準備

Scala2.9をビルドします

Day17に登場した、エルシャダイにパクr、、、インスパイヤしたち○こで有名な@yuroyoroさんの
Scalaのtrunkをビルドする - ( ꒪⌓꒪) ゆるよろ日記を参考に、githubからScalaのtrunkを落としてビルドします。
面倒なのでREPLで試します。
javaだと、RuntimeのavailableProcessorsでJVMが使えるプロセッサ数が取得できるのですが、scala.collection.parallelのパッケージオブジェクトにavailableProcessorsが定義されていました。

mbp13:bin kiyoshi$ ./scala
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
Welcome to Scala version 2.9.0.r23831-b20101223153340 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_22).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import collection.parallel
import collection.parallel

scala> parallel.availableProcessors
res0: Int = 2

うちのMacBook ProCore2 Duoなので2個使えるわけですね。
では、試してみましょう。最初にfor式を使って普通に評価します。
処理時間を計るためにBenchmarkを使って10回計測します。

scala> import testing.Benchmark
import testing.Benchmark

scala> object bench extends Benchmark {
     |   def run = for(i <- 0 to 1000) Thread.sleep(10)
     | }
defined module bench

scala> bench.runBenchmark(10)
res0: List[Long] = List(10166, 10156, 10157, 10155, 10156, 10155, 10167, 10156, 10156, 10157)

大体1回で10秒くらいかかってますね。
次に0 to 1000だったところを(0 to 1000).parと置き換えて実行します。

scala> import collection.parallel
import collection.parallel

scala> object pbench extends Benchmark {
     |   def run = for(i <- (0 to 1000).par) Thread.sleep(10)
     | }
defined module pbench

scala> pbench.runBenchmark(10)
res1: List[Long] = List(5147, 5078, 5078, 5078, 5077, 5078, 5076, 5078, 5078, 5077)

お、大体1回5秒くらいになりました!availableProcessorsが2なので期待通りです。

parってなに?

なんでこうなるのでしょうか?以下のようにすると、0 to 1000はRange.Inclusiveであることがわかります。

scala> 0 to 1000
res2: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3, ...

(0 to 1000).parは、ParRangeのインスタンスを返します。

scala> (0 to 1000).par
res3: scala.collection.parallel.immutable.ParRange = ParRange(0, 1, 2, 3, ...

ParRangeがParallel対応のRangeなのですね。他にも

  • ParArray
  • ParSet
  • ParMap

などが追加されています。
ところでparってなんでしょうか?
parはscala.collection.Parallelizableで定義されているメソッドです。

trait Parallelizable[+ParRepr <: Parallel] {

  /** Returns a parallel implementation of a collection.
   */
  def par: ParRepr

}

これを各クラスなどで実装するわけです。たとえばRangeでは

def par = new ParRange(this)

のように実装されています。

まとめ

これだけのことでプロセッサ数に対応した並列処理が出来るのは便利ですね。
for式について書きましたが、もちろんそれ以外のメソッドも並列処理してくれるようになっています。
並列処理するためのコストもありますので、並列処理すれば必ず早くなるわけではないので注意が必要です。

Scaladoc2の記法

Scaladoc2の記述について以下が参考になりました。

Scaladoc 2 | The Scala Programming Language

Authors of documentation no longer have to use HTML tags in their comments.
Instead, Scaladoc supports a wiki-like syntax very similar to that used in Trac.
In general, Scaladoc authors should no longer use HTML tags in documentation as
Scaladoc may in the future also generate documentation in other formats than
HTML.

wiki記法みたいな感じで書けるのね。で、syntaxは少し下に書いてあります。

/** This is a paragraph
*
* This is another paragraph (note the empty line above) containing '''bold''',
* ''italic'', `monospace`,
* __underline__, ^superscript^, and ,,subscript,, words.
*
* {{{
* Multi-line code can be inserted as a block and will be printed as monospace
* text.
* It isn't parsed as Scala, with keyword highlighting, but may be in the
* future.
* }}}
*
* In the near future, wiki syntax will also support bullet or number lists as
* well as links to the www and to other pages inside the documentation. */

充実はしてないけど、、、htmlタグ書くよりはマシか。

Scala2.8のPackage Objects

2.8でのパッケージオブジェクトについて書かれた文書を見つけました。
Package Objects (Martin Odersky, Lex Spoon September 15, 2010)

要約部分にこう書かれています。

Until 2.8, the only things you could put in a package were classes, traits, and standalone objects. These are by far the most common definitions that are placed at the top level of a package, but version 2.8 of the Scala programming language doesn't limit you to just those. Any kind of definition that you can put inside a class, you can also put at the top level of a package. If you have some helper method you'd like to be in scope for an entire package, go ahead and put it right at the top level of the package.

しょぼい訳をしてみると

2.8以前は、クラス、トレイト、独立したオブジェクトを置くことが出来るだけでした。これらはパッケージのトップレベルに位置する、非常に共通な定義です。しかしscala2.8ではそれらに限定しません。クラスの中に置くことの出来るどんな種類の定義でも、パッケージのトップレベルに置くことができます。もしパッケージ全体をスコープにしたい、いくつかのヘルパーメソッドがあるのなら、パッケージのトップレベルに置くことができます。

こんな感じですか。
パッケージオブジェクトの定義の仕方なども上記リンクからたどっていくことができます。

「そんなインデントで大丈夫か?」「大丈夫問題ない」

あれはまだStruts1.0が最新のFrameworkだった頃の話だったか…
僕はvimjavaのソースを書き、antなど無いからmakeでビルドしていた。1ファイルコンパイルする毎にJVMが立ち上がるため、コーヒーブレイクを入れる、そんな牧歌的な時代だった。

彼は真のアーティストだった。僕がts=4でインデントしているのを内心笑っていたに違いない。彼は僕が見たことも無い、最新式のJBuilderを使っていた。
彼のインデントは独創的だった。スペースバーを長押しする事で、誰にも真似出来ないインデントアートを生み出していく。何重にも織り込まれているif文が、論理的なネストとは相入れないインデントをなしていた。凡人である僕がその美しさを理解するには、おそらく後1世紀は必要だろう。
オートインデントを頑なに拒否する、彼のそんなストイックなところが僕には眩しかった。

そんな彼には当たりだが、try節も素晴らしいネストを幾重にも織りなし、どこで例外が発生しようが直ちにcatch出来る、まるで勧善懲悪の様式美を持つ映画を見てるようだった。
時代が時代なら、コードレビューと言う名の悪魔狩りによって、彼のソースは闇に葬り去られていたに違いない。彼と同じ時代に生まれた事を感謝せねばなるまい。

そんな彼の自慢は、3kステップのクラスを一人で作り上げた事だった。僕ではもっと細かな、複数のクラスに分かれてしまっていたに違いない。彼の前では4人のアミーゴたちですら、デザインパターンなどと言う凡人のためのカタログなど、無意味である事を思い知らされたことだろう。

・・・あれから何年が過ぎただろう。彼はふたたび、僕のプロジェクトに参加する事を望んだ。何と言うことだろう!僕は緊張しながら、彼に話を聞く事にした。
彼はデザインパターンを勉強していると言う。まさか!彼にはそんな既製品のようなプログラムは似つかわしくない。
そんな僕の心配は杞憂だった。どんなパターンを勉強しているのか尋ねた僕に彼はこう言い放った。
「パターン名とかそう言うのはちょっと…セッターとかゲッターとか、そう言うのでしょう?」

やはり彼はアーティストだった。
すっかり感心した僕は、思い切って聞いてみた。
「あの時より成長したところを教えてもらえますか?」
一呼吸おいた後、彼はゆっくり口を開いた。

「インデント出来るようになりました。」