Scala で遊んでみる
最近私のまわりでも Scala について耳にすることが増えてきましたが、私自身はこれまであまり触ったことがなかったので、少し試してみることにしました。
Scala については、関数型であることや並列処理に特化していることによく触れられています。JVM 上で動作することもあって Java の影響を強く受けていて、型安全性やオブジェクト指向言語であること、Java との親和性なども特徴としています。
最初の 1 歩ということで、Scala 言語そのものについて調べてみるというよりは、実際に動かすところまでを目標に置いてみました。
Scala を実行する
まずは言語標準の scala コマンドから Scala コードを動かしてみます。手順は以下の通りです。
Scala のインストール
前提として Java 8 以上が必要になるので、別途インストールしておきます。
その後は yum コマンドから Scala をインストールしましょう。
# yum install scala
インストール後に scala コマンドが実行できれば OK です。$ scala -version
Scala code runner version 2.10.6 -- Copyright 2002-2013, LAMP/EPFL
scala コマンドで実行する
以下の内容のソースコード factrization.scala を作成します。import scala.collection.mutable.ArrayBuffer
object Factorization {
def main(args: Array[String]): Unit = {
val random = scala.util.Random
val numbers =
if (args.isEmpty) {
// 引数で素因数分解する数値が指定されていなければ、10 個の乱数を生成する
(1 to 10).map(i => random.nextInt(Int.MaxValue))
} else {
// 引数の数値を素因数分解する
// Array 型を Vector 型に変換する
args.map(i => i.toInt).to[collection.immutable.Seq]
}
println("numbers: " + numbers.mkString(", "))
// 並列化せずに素因数分解し、その処理時間を計測する
logProcessingTime("Serial ", numbers.map(i => factorize(i)))
// 並列化して素因数分解し、その処理時間を計測する
logProcessingTime("Parallel", numbers.par.map(i => factorize(i)))
}
// 引数の数値を素因数分解し、素数のリストを返す
private def factorize(number : Int) : List[Int] = {
val list = new ArrayBuffer[Int]
var n = number
var f = 2
while (n != 1) {
if (n % f == 0) {
list += f
n /= f
} else {
f += 1
}
}
println("Thread:%3d factorize %10d to %s".format(Thread.currentThread.getId, number, list.mkString(", ")))
list.toList
}
// 第二引数の式を処理し、その処理時間を出力する
private def logProcessingTime(label: String, process: => Unit) = {
val start = System.currentTimeMillis
process
println(label + ": " + (System.currentTimeMillis - start) + "ms")
}
}
続きを読む
Scala
コメント (0) 2018/01/23 20:15:05
Linux 版 Sublime Text 3 で日本語入力変換キーを変更する
Linux (Fedora 26) で Sublime Text 3 を使っていてると、日本語入力の切り替えキーがきになります。
日本語入力への切り替えキーは、デフォルトでは Ctrl + \ というなんとも珍しいキーバインドにマッピングされています。
右の Ctrl キーを使えば片手でも打てないことはないんですが、BackSpace が近いのと、完全にホームポジションから手が離れるのが気になります。
他にいいキーバインドはないものかといろいろ試してみたのですが、結局 Ctrl + Space に落ち着いたので、その設定方法を書いておこうと思います。
Ctrl + Space というと Fedora Core 時代のようで少し懐かしいですね。
Sublime Text 3 のキーマップを変更する
メニューバーの Preferences > Key Bindings を選択します。
キーバインドを設定するための Default (Linux).sublime-keymap - Default と Default (Linux).sublime-keymap - User というタブが開くので、ユーザーの設定を書く Default (Linux).sublime-keymap - User の方に以下の内容を記載し、保存します。[
{ "keys": ["ctrl+space"], "command": "toggle_mozc" }
]
これで OK です。
続きを読む
Linux
コメント (0) 2018/01/21 12:00:03
sqlite3 で SELECT 結果の行番号を取得する
SQL を使っていると、SELECT した結果セットの各行について、結果セット中での行番号を知りたい、という場面にたまに遭遇します。こういうやつです。SELECT * FROM books ORDER BY price;
id title price
---------- -------------- ----------
3 Art with Basis 600 #行番号: 1
4 Book List 990 #行番号: 2
1 Civilizations 1000 #行番号: 3
2 Dream Post 1200 #行番号: 4
5 El sant magina 1500 #行番号: 5
一般的な一覧系の処理では先頭から N 件とりだすことが多いので、OFFSET で取り出した件数を指定すれば行番号を意識せずに続きをとることができます。
ただ、ID からその行の結果セット中での位置を知ろうとすると、やはり行番号が欲しくなってくるのです。結果セットがソートされていたり、ソートされているカラムがユニークでなかったりするとかなり面倒なことになります。特定の ID の行の前後 3 行ずつを取りたい、というような時に困ってしまうわけです。
結果セット中での行番号を取得するために、Oracle では ROWNUM 擬似列や ROW_NUMBER() 関数が用意されているそうです。
また、MySQL ではユーザ定義変数を使うことで、SELECT 時に行番号を計算し、出力することができます。SET @rownum := 0; SELECT *, (@rownum := @rownum + 1) FROM books;
しかし sqlite3 では ROW_NUMBER() 的な機能もユーザー定義変数的な機能も実装されていないので、これらの方針をとることはできません。ネットを見てみると以下のようなクエリで計算している例がありますが、境界値として WHERE 句で使っているカラム(ここでは id カラム)がユニークでない場合、境界値として機能しないため、厳密な行番号はとれません。SELECT id, title, price, (SELECT COUNT(*) FROM books b2 WHERE b1.id >= b2.id) AS rownum FROM books b1 ORDER BY rownum;
id title price rownum
---------- -------------- ---------- ----------
3 Art with Basis 600 1
4 Book List 990 2
1 Civilizations 1000 3
2 Dream Post 1200 4
5 El sant magina 1500 5
※ ORDER BY rownum は見やすさ重視のためにつけたもので、必須ではありません。
もう 1 点、この方法では 1 行毎にサブクエリで行番号をカウントするため、参照性能に問題があります。MySQL では悪名高き DEPENDENT SUBQUERY にあたるためです。
続きを読む
WEB 技術
コメント (0) 2017/02/01 19:45:13