SlideShare a Scribd company logo
1 of 74
Download to read offline
あなたのScalaを爆速に
する7つの方法
x1(井上 ゆり)
For ScalaMatsuri 2016
7 ways to make your Scala RedHot high velocity
井上 ゆり
株式会社サイバーエージェント
アドテクスタジオ AMoAd.
twitter: @iyunoriue
GitHub: x1-
HP: バツイチとインケンのエンジニアブログ
http://x1.inkenkun.com/
profile
I m Yuri Inoue.
• このスライドに出てくる速度やパフォーマンスは並列実行
を考慮していません。
• このセッションはScalaビギナーを対象としています。
• ベンチマークを取得した環境は次ページに表示します。
• パフォーマンスについて@Keenからいくつかのアドバイスを
頂きました。ありがとう!
acknowledgement
ack. Parallel execution is not taken into account.
environment of benchmark
インスタンス Amazon EC2 m3.2xlarge
vCPU 8
memory 30GB
ディスク 汎用SSD
OS CentOS6.7-Final
jdk jdk1.8.0u65(oracle, server vm)
scala 2.11.7
ビルドツール sbt
ベンチマークツール sbt-jmh 0.2.5
使用ライブラリ
com.bionicspirit.shade:1.6.0
net.debasishg.redisclient:3.0
org.scalatest.scalatest:2.2.4
environment of benchmark.
No.1 ランダム・リード
- ファイル vs KVS -
Q1
2GBのデータの中に、
ある文字列がいくつ存在す
るか数えます。
次のうちどちらの方が速い
でしょう?
When searching for string, which one would be faster?
SSD上の
2GBファイル
A
memcache上の
2GBデータ
(チャンク分割)
B
前提条件 前提条件
* SSDはAmazon EC2の
汎用SSDです。
* RamDiskは使ってい
ません。
* memcacheのバージョ
ンは1.4.0です。
* memcacheはローカル
に存在します。
A:from 2GB file on SSD B:2GB data on memcache
Answer
A. SSD上の2GBファイル
Ans. A. from 2GB file on SSD.
benchmark
上記のグラフは、下記のような2GBのデータから”SUIKA”
という文字列を探したときの平均タイムです。
• ファイルの場合は8秒未満で完了します。
• memcacheの場合は19秒近くかかりました。
• memcacheと同じKVSのRedisでは14秒弱でした。
'''<code>&amp;h</code>''' を用い、<code>&amp;h0F</code> (十進で15)のように表現する。
nn[[Standard Generalized Markup Language|SGML]]、[[Extensible Markup Language|XML]]、
[[HyperText Markup Language|HTML]]では、アンパサンドをSUIKA使って[[SGML実体]]を参照する。
the average for the time searching string - SUIKA .
Why is file faster than memcache?
• ファイルの読み込みに Memory Mapped File(MMF) を利用しまし
た。
• Memory Mapped File は、ファイルをメモリの連続領域にマッピ
ングして操作する機能です。
• ユーザ空間での不必要なファイルI/O操作なしにディスク上の
ファイルの内容をバッファリングすることができます。
• java.nioパッケージには Memory Mapped File にダイレクト・
アクセスするMappedByteBufferがあります。
物理
ファイル
メモリ空間にマッピング
This is Memory Mapped File(MMF) power.
• memcache(<1.4.2)は下記の制約があります。
1キーに格納できる最大サイズは1MBです.
• 同一ホスト上のmemcacheだとしても、何度もデータを取得する
のはそれなりにコストがかかります。
• 1キーに1GBまで格納できるRedisを使って、2GBのデータを500MB
づつ4キーに分割し、検索したときのベンチマークが下記です。
• 8秒強で完了しますが、それでもMMFには勝てませんでした。
Why is memcache slower than file?
memcache(<1.4.2) has 1key=1MB limitation.
• しかし、JVM環境でのMemory Mapped Fileは2GBまでしか
マッピングできません。
http://stackoverflow.com/questions/8076472/why-does-
filechannel-map-take-up-to-integer-max-value-of-data
• Apache Spark MLlib開発責任者のReynold XinさんがGistに
ByteBufferシリーズのパフォーマンス計測を記述していま
す。
これはScalaで書かれていてとても参考になります。
https://gist.github.com/rxin/5087680
more information
MMF can map only map up to 2GB file on JVM.
爆速 No.1
Memory Mapped Fileで
高速ファイル操作が可能に!
No.1 using MMF, you can operate on files at high speed!
No.2 for内包表記
vs
flatMap & map
Q2
for内包表記とflatMap & map
は結果同じ挙動をとりますが
どちらが速いでしょう?
for comprehension and flatMap&map which is faster?
A B
code
同じ flatMap & map
for {

a <- data

b <- a

} yield {

b

}
for内包表記
data.flatMap( a =>
a.map( b => b )
)
flatMap & map
Answer
A. 同じ
Ans. A.same.
benchmark
Throughput、Average、Sample のいずれも for内包表
記 と flatMap & map で優位差が見られませんでした。
10,000回
The benchmark doesn t show significant difference.
• for内包表記 と flatMap & map は論理的に同じです。
• 下記はデコンパイルしたコードですが全く同じです。
Why are they the same speed?
for comprehension and flatMap&map are logically same.
public Option<String> forComprehension()

{

data().flatMap(new AbstractFunction1()

{

public static final long serialVersionUID = 0L;



public final Option<String> apply(Some<String> a)

{

a.map(new AbstractFunction1()

{

public static final long serialVersionUID = 0L;



public final String apply(String b)

{

return b;

}

});

}

});

}
public Option<String> flatMapAndMap()

{

data().flatMap(new AbstractFunction1()

{

public static final long serialVersionUID = 0L;



public final Option<String> apply(Some<String> a)

{

a.map(new AbstractFunction1()

{

public static final long serialVersionUID = 0L;



public final String apply(String b)

{

return b;

}

});

}

});

}
for comprehension flatMap & map
爆速 No.2
for内包表記 と flatMap & map は
バイト・コードのレベルで同じです。
No.2 for comprehension and flatMap&map are same.
No.3 追加と挿入
- collection -
ScalaにおけるCollectionの性能特性
引用: http://docs.scala-lang.org/ja/overviews/collections/performance-characteristics.html
Collections Performance Characteristics at Scala.
Q3-1
可変な “var xs: Vector”
と
不変な “val xs: ArrayBuffer”
末尾追加が速いのはどちらでしょう?
When appending Vector or ArrayBuffer, which is faster?
var Vector
A
val ArrayBuffer
B
code
var xs = Vector.empty[Int]
xs = xs :+ a
var xs: Vector val xs: ArrayBuffer
val xs = ArrayBuffer.empty[Int]
xs += a
Answer
B. val ArrayBuffer
Ans. B.val ArrayBuffer.
benchmark
ArrayBuffer の方が Vector よりも速いです。
ArrayBuffer is faster than Vector.
n回追加したときのThroughput
上記のグラフはN個の要素を追加したときのスループットを表しています。
例えばtypeがVector, timesが10kの場合では、10,000個の要素を空のVectorに追
加したときのスループットを意味しています。
benchmark
他のimmutableオブジェクトのベンチマークは下記のとおり
です。
Vector is faster than List and Stream.
n回追加したときのThroughput
Vector は同じimmutableオブジェクトの List や
Stream よりは速いです。
Why is ArrayBuffer faster than Vector?
新しく要素を追加するときのコードを比較してみます。
These processes are absolutely different.
新しいインスタンスに既存の
要素をコピーしてから新しい
要素を追加します。
インスタンスのリサイズを行っ
てから末尾の要素を新要素で
更新します。
var Vector val ArrayBuffer
val b = bf(repr)

b ++= thisCollection

b += elem

b.result()
ensureSize(size0 + 1)

array(size0) =
elem.asInstanceOf[AnyRef]

size0 += 1

this
Vector と ArrayBuffer でプロセスが全く異なります。
Q3-2
可変な “var xs: List”
と
不変な “val xs: ListBuffer”
先頭挿入が速いのはどちらでしょう?
When inserting into List or ListBuffer, which is faster?
var List
A
val ListBuffer
B
code
var xs = List.empty[Int]
xs = a :: xs
var xs: List val xs: ListBuffer
val xs = ListBuffer.empty[Int]
a +=: xs
Answer
A. var List
Ans. A.var List
benchmark
List の方が ListBuffer よりも速いです。
List is faster than ListBuffer.
n回先頭挿入したときのThroughput
上記のグラフはN個の要素を先頭に追加したときのスループットを表しています。
例えばtypeがList, timesが1kの場合では、1,000個の要素を空のListの先頭に挿
入していったときのスループットを意味しています。
benchmark
他のオブジェクトのベンチマークは下記のとおりです。
List is enormously faster than the others.
List だけ飛び抜けて速いです。
n回先頭挿入したときのThroughput
Why is List faster than the others?
要素を先頭挿入するときのコードを比較してみます。
List calculate a little, in case of inserting.
Listは先頭とその他の要素を
別管理しているため、新しい
要素をすぐに作れます。
ListBufferはListとほとんど
一緒なのですが内部変数の再
代入が行われます。
var List val ListBuffer
new
scala.collection.immutable
.::(x, this)
if (exported) copy()

val newElem = new :: (x, start)

if (isEmpty) last0 = newElem

start = newElem

len += 1

this
List ではほとんど計算せずに先頭挿入が行えます。
爆速 No.3
末尾追加のときは ArrayBuffer や
ListBuffer を使うと効率が良いです。
しかし先頭挿入のときは List を使うと
良いパフォーマンスが得られます。
No.3 appending => **Buffer, inserting => List are nice.
No.4 削除
- collection -
Q4
可変な “var xs: List”
と
不変な “val xs: ListBuffer”
削除が速いのはどちらでしょう?
When removing from List or ListBuffer, which is faster?
var List
A
val ListBuffer
B
code
var xs: List val xs: ListBuffer
var xs =
List( 1 to n: _* )
// head
xs = xs.tail
// tail
xs = xs.dropRight(0)
var xs =
ListBuffer( 1 to n: _* )
// head
xs.remove(0)
// tail
xs.remove(xs.size - 1)
Answer
B. val ListBuffer
Ans. B.val ListBuffer
benchmark
ListBuffer は List よりも相当速いです。
ListBuffer is much faster than List.
n回削除したときのThroughput
上記のグラフはN個の要素をサイズNのコレクションから削除したときのスループットを
表しています。
例えば、Benchmark:removeTail, type:List, times:1kの場合では サイズ1,000のList
の末尾から1,000回要素削除を行ったときのスループットを意味します。
benchmark
他のオブジェクトのベンチマークは下記のとおりです。
They are too slow, expecting Buffer family.
Buffer 系以外はどれも超絶遅いです。
n回削除したときのThroughput
Why is ListBuffer faster than List?
要素を削除するときのコードを比較してみます。
The operation dropRight of List takes time O(n).
ListのdropRightの操作はO(n)
の時間がかかります。
ListBufferのremove操作は定
数時間です。
var List val ListBuffer
def dropRight(n: Int): Repr = {

val b = newBuilder

var these = this

var lead = this drop n

while (!lead.isEmpty) {

b += these.head

these = these.tail

lead = lead.tail

}

b.result()

}
def remove(n: Int): A = {
:
var cursor = start

var i = 1

while (i < n) {

cursor = cursor.tail

i += 1

}

old = cursor.tail.head

if (last0 eq cursor.tail) last0 =
cursor.asInstanceOf[::[A]]

cursor.asInstanceOf[::[A]].tl
= cursor.tail.tail
benchmark of List’s dropRight
このベンチマークは10倍づつサイズを増やしているので、ス
ループットも底10で対数表示します。
Throughput is just only lowered to linear.
スループットはただ線形に下降しているだけです。
操作時間線形増加の恐怖です。
Q3で出てきたVectorの末尾追加も線形増加なのですが、同じ線形増加でも削除のほうが
増加率が大きいので、パフォーマンスがすごく落ちているように感じます。
List - dropRightのlog(Throughput)
reference benchmark
Comparing dropRight with take.
dropRight(1) と take(n-1) で同じ機能を実現できる
ので、dropRight と take を比較しました。
take は dropRight より少しだけ速いです。
Throughput of List’ dropRight and take
爆速 No.4
たくさんの要素を削除するときは
ListBuffer や ArrayBuffer を使うと
効率が良いです。
No.4 When removing element, **Buffer are good.
削除に限らずなんですが、基本的にはimmutableなオブジェクトよりもmutableな
Buffer系の方が書き込み操作は速いです。
No.5 ランダム・リード
- collection -
Q5
Vector と ListBuffer
ランダム・リードが速いのは
どちらでしょう?
When reading from Vector or ListBuffer,which is faster?
Vector
A
ListBuffer
B
code
val data =
Vector( 1 to n: _* )



( 1 to data.size ) map { _ =>
data( Random.nextInt( n ) )
}
val data =
ListBuffer( 1 to n: _* )



( 1 to data.size ) map { _ =>
data( Random.nextInt( n ) )
}
Answer
A. Vector
Ans. A.Vector
benchmark
Vector は ListBuffer より速いです。
Vector is faster than ListBuffer.
n個の要素をreadしたときのThroughput
上記のグラフはサイズNのコレクションからランダムにN回要素を取得したときの
スループットを表しています。
例えば、 type:ListBuffer, times:1k の場合、サイズ1,000のListからランダム
に1,000回要素を取得することを意味します。
benchmark
他のオブジェクトのベンチマークは下記のとおりです。
Array, ArrayBuffer, Vector are fast.
速いのは Array, ArrayBuffer, Vector です。
n個の要素をreadしたときのThroughput
Why Array, ArrayBuffer, Vector are fast?
Such as Vector uses Array - constant time - internal.
• Array のランダム・リードは定数時間です。
• ArrayBuffer と Vector は内部的に Array を使っています。
protected var array: Array[AnyRef]
= new Array[AnyRef](math.max(initialSize, 1))
:
def apply(idx: Int) = {

if (idx >= size0) throw new IndexOutOfBoundsException(idx.toString)

array(idx).asInstanceOf[A]

}
例) ArrayBuffer
爆速 No.5
Array の仲間は
ランダム・リードが速いです。
No5. It s cool using Array family when reading randomly.
No.6 フィボナッチ数列
Q6
上記を踏まえて、
Stream と Array
どちらがより速く
フィボナッチ数列をつくる
ことができるでしょうか?
Stream or Array, which is producing fibonacci faster?
Stream
A
Array
B
* 再帰的に計算します。
* 計算量O(n)のロジック
です。
code
def fibonacci(
h: Int = 1,
n: Int = 1 ): Stream[Int] =

h #:: fibonacci( n, h + n )
val fibo = fibonacci().take( n )
def fibonacci( n: Int = 1 ): Array[Int] =
if ( n == 0 ) {

Array.empty[Int]

} else {

val b = new Array[Int](n)

b(0) = 1

for ( i <- 0 until n - 1 ) {

val n1 = if ( i == 0 ) 0 else b( i - 1 )

val n2 = b( i )

b( i + 1 ) = n1 + n2

}

b

}
val fibo = fibonacci( n )
Answer
A. Stream.
Ans. A.Streamです。
benchmark
Stream は Array よりも圧倒的に速いです。
Stream is overwhelmingly faster than Array.
長さnのフィボナッチ数列をつくったときのスループット
フィボナッチ数列: ( 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, .. )
Why is Stream so much faster?
Stream implements lazy list evaluated when needed.
• Stream は遅延評価リストを実装しているので必要なときに
だけ計算されます。
• 実際fibonacciメソッド(前ページ)を呼び出した時点ではフィ
ボナッチ数列はまだ計算されていません。
• これが遅延評価の力です。
• しかし数列が具現化されるときにはそれなりの計算時間を
必要とします。
→ 次ページをごらんください。
Why is Stream so much faster?
if the sequence is materialized, it takes calculating time.
Stream の toList を実行したときのベンチマークです。
Stream で toList を実行すると、Array が最も速いです。
これは Array で使っている計算ロジックが再帰による計算
よりも速いことを示します。
長さnのフィボナッチ数列をつくったときのスループット
爆速 No.6
遅延評価は便利です。
しかし具現化するときにはそれなりの
コストがかかるのをお忘れなく。
No.6 lazy evaluation is very useful.
No.7 正規表現
Showing the benchmark of w+w
正規表現はCPUリソースをたくさん消費します。
特に、“ww..w”のようなバック・トラッキングが発生
する表現では計算量O(n^2)となります。
Regular Expression consumes CPU resource a lot.
下のグラフは正規表現のパフォーマンスです。
各正規表現1,000回実行時のスループット
最終問題. Q7
ある表現(w+/)の後方を探したいです。
“findAllIn & 肯定的後読み(?<=)”
と
“findPrefixOf & 量指定子(+)”
どちらが速いでしょう?
次の文字列から探します→ abcdef..0123../abc.. (1024byte)
ある文字列の後方を探したいです。どちらが速いでしょう?
同じ
A
findPrefixOf
B
code
val re = """(?<=w+)/.+""" r
val ms = re findAllIn data

if ( ms.isEmpty ) None

else Some( ms.next )
val re = “""w+/""" r

re findPrefixMatchOf data map(
_.after.toString
)
findAllIn と 肯定的後読み findPrefixOf と 量指定子
Answer
B. findPrefixOf
と量指定子(+)
Ans. B.findPrefixOf & quantifier(+).
benchmark
findPrefixOf and quantifier is faster than findAllIn.
findPrefixOf と 量指定子(+) の組み合わせの方が
findAllIn より速いです。
1,000回実行時のスループット
上記のグラフは、findAllInと正規表現“(?<=w+)/.+”、findPrefixOfと正規表現
“w/”をN回実行したときのスループットを表しています。
Why are findPrefixOf and quantifier faster?
findAllIn returns all matches, findPrefixOf returns head.
• 上記の表現はバック・トラッキングを引き起こします。
• 肯定的後読みは問題ではありません。
• 加えて、このケースでは findPrefixOf は findAllIn より速
く動作します。
• findAllIn は対象文字列中でマッチした部分を全て返します。
• findPrefixOf は対象文字列の先頭が正規表現にマッチした場
合のみマッチ部分を返します。
(?<=w+)/.+
同じ文字列にマッチしてしまう...!
benchmark of various regular expressions
Even if given same regex, findPrefixOf is fastest.
同じ正規表現を実行しても findPrefixOf が一番速いです。
findPrefixOf と 肯定的後読みの組み合わせは良いパフォーマンスが
得られます。
1,000回実行時のスループット
findPrefixOf usage in famous library
ルーティング・ツリーはURIパスの先頭から構築するので、
findAllIn よりも findPrefixOf が適しています。
findPrefixOf is used in spray-routing.
implicit def regex2PathMatcher(regex: Regex): PathMatcher1[String] =
regex.groupCount match {

case 0 ⇒ new PathMatcher1[String] {

def apply(path: Path) = path match {

case Path.Segment(segment, tail) ⇒ regex findPrefixOf segment match {

case Some(m) ⇒ Matched(segment.substring(m.length) :: tail, m :: HNil)

case None ⇒ Unmatched

}

case _ ⇒ Unmatched

}

}
:
https://github.com/spray/spray/blob/master/spray-routing/src/main/scala/spray/routing/PathMatcher.scala
PathMatcher.scala line:211
下記は spray-routing のコードを一部抜粋したものです。
爆速 No.7
findPrefixOf は結構便利です。
正規表現を使うときは、その計算量を
考えましょう。
No.7. When using Regex, be mindful of the computation.
No. 1 Memory Mapped File で高速ファイル操作が可能に!
No. 2 for内包表記 と flatMap & map はバイト・コードのレベルで
同じです。
No. 3 コレクションを沢山更新するようなときは ArrayBuffer や
ListBuffer などの Buffer系 を使うと効率が良いです。
No. 4 List は 先頭挿入で最も良いパフォーマンスを示すので、List
を使うときは先頭挿入した後にソートして使うとよいです。
No. 5 Array の仲間はランダム・リードが速いので何度も読みだすと
きは大活躍です。
No. 6 遅延評価は便利です。しかし具現化するときにはそれなりのコ
ストがかかるのをお忘れなく。
No. 7 findPrefixOf は結構便利です。そして正規表現を使うとき
は、その計算量を考えましょう。
https://github.com/x1-/scala-benchmark
ベンチマーク計測に使ったソースコードは
こちらに公開しています。
Thank you for listening!

More Related Content

What's hot

分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれKumazaki Hiroki
 
マイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチマイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチ増田 亨
 
リクルートのWebサービスを支える「RAFTEL」
リクルートのWebサービスを支える「RAFTEL」リクルートのWebサービスを支える「RAFTEL」
リクルートのWebサービスを支える「RAFTEL」Recruit Technologies
 
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjug実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjugYahoo!デベロッパーネットワーク
 
とある診断員とSQLインジェクション
とある診断員とSQLインジェクションとある診断員とSQLインジェクション
とある診断員とSQLインジェクションzaki4649
 
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはがんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはJun-ichi Sakamoto
 
ラムダと invokedynamic の蜜月
ラムダと invokedynamic の蜜月ラムダと invokedynamic の蜜月
ラムダと invokedynamic の蜜月Taku Miyakawa
 
Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり
Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり
Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり Rakuten Group, Inc.
 
Fluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンFluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンKentaro Yoshida
 
本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話Kumazaki Hiroki
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」Takuto Wada
 
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャーKubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャーToru Makabe
 
JVMのGCアルゴリズムとチューニング
JVMのGCアルゴリズムとチューニングJVMのGCアルゴリズムとチューニング
JVMのGCアルゴリズムとチューニング佑哉 廣岡
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方増田 亨
 
トランザクションの設計と進化
トランザクションの設計と進化トランザクションの設計と進化
トランザクションの設計と進化Kumazaki Hiroki
 
GKE に飛んでくるトラフィックを 自由自在に操る力 | 第 10 回 Google Cloud INSIDE Games & Apps Online
GKE に飛んでくるトラフィックを 自由自在に操る力 | 第 10 回 Google Cloud INSIDE Games & Apps OnlineGKE に飛んでくるトラフィックを 自由自在に操る力 | 第 10 回 Google Cloud INSIDE Games & Apps Online
GKE に飛んでくるトラフィックを 自由自在に操る力 | 第 10 回 Google Cloud INSIDE Games & Apps OnlineGoogle Cloud Platform - Japan
 
入社1年目のプログラミング初心者がSpringを学ぶための手引き
入社1年目のプログラミング初心者がSpringを学ぶための手引き入社1年目のプログラミング初心者がSpringを学ぶための手引き
入社1年目のプログラミング初心者がSpringを学ぶための手引き土岐 孝平
 
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本Takahiro YAMADA
 
イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)Yoshitaka Kawashima
 
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)NTT DATA Technology & Innovation
 

What's hot (20)

分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれ
 
マイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチマイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチ
 
リクルートのWebサービスを支える「RAFTEL」
リクルートのWebサービスを支える「RAFTEL」リクルートのWebサービスを支える「RAFTEL」
リクルートのWebサービスを支える「RAFTEL」
 
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjug実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
 
とある診断員とSQLインジェクション
とある診断員とSQLインジェクションとある診断員とSQLインジェクション
とある診断員とSQLインジェクション
 
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはがんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
 
ラムダと invokedynamic の蜜月
ラムダと invokedynamic の蜜月ラムダと invokedynamic の蜜月
ラムダと invokedynamic の蜜月
 
Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり
Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり
Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり
 
Fluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンFluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターン
 
本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
 
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャーKubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
 
JVMのGCアルゴリズムとチューニング
JVMのGCアルゴリズムとチューニングJVMのGCアルゴリズムとチューニング
JVMのGCアルゴリズムとチューニング
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方
 
トランザクションの設計と進化
トランザクションの設計と進化トランザクションの設計と進化
トランザクションの設計と進化
 
GKE に飛んでくるトラフィックを 自由自在に操る力 | 第 10 回 Google Cloud INSIDE Games & Apps Online
GKE に飛んでくるトラフィックを 自由自在に操る力 | 第 10 回 Google Cloud INSIDE Games & Apps OnlineGKE に飛んでくるトラフィックを 自由自在に操る力 | 第 10 回 Google Cloud INSIDE Games & Apps Online
GKE に飛んでくるトラフィックを 自由自在に操る力 | 第 10 回 Google Cloud INSIDE Games & Apps Online
 
入社1年目のプログラミング初心者がSpringを学ぶための手引き
入社1年目のプログラミング初心者がSpringを学ぶための手引き入社1年目のプログラミング初心者がSpringを学ぶための手引き
入社1年目のプログラミング初心者がSpringを学ぶための手引き
 
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本
 
イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)
 
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
 

Viewers also liked

統計をとって高速化する
Scala開発
統計をとって高速化する
Scala開発統計をとって高速化する
Scala開発
統計をとって高速化する
Scala開発Mitsuki Ogasahara
 
Scalaプロダクトのビルド高速化
Scalaプロダクトのビルド高速化Scalaプロダクトのビルド高速化
Scalaプロダクトのビルド高速化kuro kuro
 
Scala Refactoring for Fun and Profit (Japanese subtitles)
Scala Refactoring for Fun and Profit (Japanese subtitles)Scala Refactoring for Fun and Profit (Japanese subtitles)
Scala Refactoring for Fun and Profit (Japanese subtitles)Tomer Gabel
 
Contributing to Scala OSS from East Asia #ScalaMatsuri
 Contributing to Scala OSS from East Asia #ScalaMatsuri Contributing to Scala OSS from East Asia #ScalaMatsuri
Contributing to Scala OSS from East Asia #ScalaMatsuriKazuhiro Sera
 
How Scala code is expressed in the JVM
How Scala code is expressed in the JVMHow Scala code is expressed in the JVM
How Scala code is expressed in the JVMKoichi Sakata
 
Why Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuriWhy Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuriYuta Okamoto
 
バッチを Akka Streams で再実装したら100倍速くなった話 #ScalaMatsuri
バッチを Akka Streams で再実装したら100倍速くなった話 #ScalaMatsuriバッチを Akka Streams で再実装したら100倍速くなった話 #ScalaMatsuri
バッチを Akka Streams で再実装したら100倍速くなった話 #ScalaMatsuriKazuki Negoro
 

Viewers also liked (9)

統計をとって高速化する
Scala開発
統計をとって高速化する
Scala開発統計をとって高速化する
Scala開発
統計をとって高速化する
Scala開発
 
Scalaプロダクトのビルド高速化
Scalaプロダクトのビルド高速化Scalaプロダクトのビルド高速化
Scalaプロダクトのビルド高速化
 
ScalaMatsuri 2016
ScalaMatsuri 2016ScalaMatsuri 2016
ScalaMatsuri 2016
 
Scala Refactoring for Fun and Profit (Japanese subtitles)
Scala Refactoring for Fun and Profit (Japanese subtitles)Scala Refactoring for Fun and Profit (Japanese subtitles)
Scala Refactoring for Fun and Profit (Japanese subtitles)
 
Contributing to Scala OSS from East Asia #ScalaMatsuri
 Contributing to Scala OSS from East Asia #ScalaMatsuri Contributing to Scala OSS from East Asia #ScalaMatsuri
Contributing to Scala OSS from East Asia #ScalaMatsuri
 
How Scala code is expressed in the JVM
How Scala code is expressed in the JVMHow Scala code is expressed in the JVM
How Scala code is expressed in the JVM
 
Why Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuriWhy Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuri
 
バッチを Akka Streams で再実装したら100倍速くなった話 #ScalaMatsuri
バッチを Akka Streams で再実装したら100倍速くなった話 #ScalaMatsuriバッチを Akka Streams で再実装したら100倍速くなった話 #ScalaMatsuri
バッチを Akka Streams で再実装したら100倍速くなった話 #ScalaMatsuri
 
Zen of Akka
Zen of AkkaZen of Akka
Zen of Akka
 

Similar to あなたのScalaを爆速にする7つの方法(日本語版)

関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)啓 小笠原
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Ransui Iso
 
PythonでLispを実装した (evalつき)
PythonでLispを実装した (evalつき)PythonでLispを実装した (evalつき)
PythonでLispを実装した (evalつき)t-sin
 
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キューYuto Takei
 
Functional JavaScript with Lo-Dash.js
Functional JavaScript with Lo-Dash.jsFunctional JavaScript with Lo-Dash.js
Functional JavaScript with Lo-Dash.jsShogo Sensui
 
PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)
PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)
PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)Satoshi Yamada
 
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けープログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けーTanUkkii
 
関数プログラミング入門
関数プログラミング入門関数プログラミング入門
関数プログラミング入門Hideyuki Tanaka
 
Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Ra Zon
 
JavaScript 講習会 #1
JavaScript 講習会 #1JavaScript 講習会 #1
JavaScript 講習会 #1Susisu
 
より深く知るオプティマイザとそのチューニング
より深く知るオプティマイザとそのチューニングより深く知るオプティマイザとそのチューニング
より深く知るオプティマイザとそのチューニングYuto Hayamizu
 
Coq 20100208a
Coq 20100208aCoq 20100208a
Coq 20100208atmiya
 
PostgreSQL SQLチューニング入門 実践編(pgcon14j)
PostgreSQL SQLチューニング入門 実践編(pgcon14j)PostgreSQL SQLチューニング入門 実践編(pgcon14j)
PostgreSQL SQLチューニング入門 実践編(pgcon14j)Satoshi Yamada
 

Similar to あなたのScalaを爆速にする7つの方法(日本語版) (20)

関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3
 
たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
PythonでLispを実装した (evalつき)
PythonでLispを実装した (evalつき)PythonでLispを実装した (evalつき)
PythonでLispを実装した (evalつき)
 
pi-6. 繰り返し
pi-6. 繰り返しpi-6. 繰り返し
pi-6. 繰り返し
 
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー
 
Functional JavaScript with Lo-Dash.js
Functional JavaScript with Lo-Dash.jsFunctional JavaScript with Lo-Dash.js
Functional JavaScript with Lo-Dash.js
 
PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)
PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)
PostgreSQLの実行計画を読み解こう(OSC2015 Spring/Tokyo)
 
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けープログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
 
関数プログラミング入門
関数プログラミング入門関数プログラミング入門
関数プログラミング入門
 
HiRoshimaR3_IntroR
HiRoshimaR3_IntroRHiRoshimaR3_IntroR
HiRoshimaR3_IntroR
 
Rの高速化
Rの高速化Rの高速化
Rの高速化
 
Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]
 
Scala on Hadoop
Scala on HadoopScala on Hadoop
Scala on Hadoop
 
JavaScript 講習会 #1
JavaScript 講習会 #1JavaScript 講習会 #1
JavaScript 講習会 #1
 
より深く知るオプティマイザとそのチューニング
より深く知るオプティマイザとそのチューニングより深く知るオプティマイザとそのチューニング
より深く知るオプティマイザとそのチューニング
 
Coq 20100208a
Coq 20100208aCoq 20100208a
Coq 20100208a
 
PostgreSQL SQLチューニング入門 実践編(pgcon14j)
PostgreSQL SQLチューニング入門 実践編(pgcon14j)PostgreSQL SQLチューニング入門 実践編(pgcon14j)
PostgreSQL SQLチューニング入門 実践編(pgcon14j)
 
Rcppのすすめ
RcppのすすめRcppのすすめ
Rcppのすすめ
 
ATN No.2 Scala事始め
ATN No.2 Scala事始めATN No.2 Scala事始め
ATN No.2 Scala事始め
 

More from x1 ichi

リアルタイムにデータ分析してWebサービスの面白さを伝えたい
リアルタイムにデータ分析してWebサービスの面白さを伝えたいリアルタイムにデータ分析してWebサービスの面白さを伝えたい
リアルタイムにデータ分析してWebサービスの面白さを伝えたいx1 ichi
 
逆引き!Scala x ビッグデータ
逆引き!Scala x ビッグデータ逆引き!Scala x ビッグデータ
逆引き!Scala x ビッグデータx1 ichi
 
競馬の格言を地方競馬で検証してみた
競馬の格言を地方競馬で検証してみた競馬の格言を地方競馬で検証してみた
競馬の格言を地方競馬で検証してみたx1 ichi
 
あなたのScalaを爆速にする7つの方法
あなたのScalaを爆速にする7つの方法あなたのScalaを爆速にする7つの方法
あなたのScalaを爆速にする7つの方法x1 ichi
 
本当にあったApache Spark障害の話
本当にあったApache Spark障害の話本当にあったApache Spark障害の話
本当にあったApache Spark障害の話x1 ichi
 
MillWheel Fault-Tolerant Stream Processing at Internet Scaleの意訳
MillWheel Fault-Tolerant Stream Processing at Internet Scaleの意訳MillWheel Fault-Tolerant Stream Processing at Internet Scaleの意訳
MillWheel Fault-Tolerant Stream Processing at Internet Scaleの意訳x1 ichi
 
広告配信現場で使うSpark機械学習
広告配信現場で使うSpark機械学習広告配信現場で使うSpark機械学習
広告配信現場で使うSpark機械学習x1 ichi
 
女性エンジニアの1週間
女性エンジニアの1週間女性エンジニアの1週間
女性エンジニアの1週間x1 ichi
 
Sparkを用いたビッグデータ解析 〜 前編 〜
Sparkを用いたビッグデータ解析 〜 前編 〜Sparkを用いたビッグデータ解析 〜 前編 〜
Sparkを用いたビッグデータ解析 〜 前編 〜x1 ichi
 
解説: a semantic approach to recommending text advertisements for images
解説: a semantic approach to recommending text advertisements for images解説: a semantic approach to recommending text advertisements for images
解説: a semantic approach to recommending text advertisements for imagesx1 ichi
 

More from x1 ichi (10)

リアルタイムにデータ分析してWebサービスの面白さを伝えたい
リアルタイムにデータ分析してWebサービスの面白さを伝えたいリアルタイムにデータ分析してWebサービスの面白さを伝えたい
リアルタイムにデータ分析してWebサービスの面白さを伝えたい
 
逆引き!Scala x ビッグデータ
逆引き!Scala x ビッグデータ逆引き!Scala x ビッグデータ
逆引き!Scala x ビッグデータ
 
競馬の格言を地方競馬で検証してみた
競馬の格言を地方競馬で検証してみた競馬の格言を地方競馬で検証してみた
競馬の格言を地方競馬で検証してみた
 
あなたのScalaを爆速にする7つの方法
あなたのScalaを爆速にする7つの方法あなたのScalaを爆速にする7つの方法
あなたのScalaを爆速にする7つの方法
 
本当にあったApache Spark障害の話
本当にあったApache Spark障害の話本当にあったApache Spark障害の話
本当にあったApache Spark障害の話
 
MillWheel Fault-Tolerant Stream Processing at Internet Scaleの意訳
MillWheel Fault-Tolerant Stream Processing at Internet Scaleの意訳MillWheel Fault-Tolerant Stream Processing at Internet Scaleの意訳
MillWheel Fault-Tolerant Stream Processing at Internet Scaleの意訳
 
広告配信現場で使うSpark機械学習
広告配信現場で使うSpark機械学習広告配信現場で使うSpark機械学習
広告配信現場で使うSpark機械学習
 
女性エンジニアの1週間
女性エンジニアの1週間女性エンジニアの1週間
女性エンジニアの1週間
 
Sparkを用いたビッグデータ解析 〜 前編 〜
Sparkを用いたビッグデータ解析 〜 前編 〜Sparkを用いたビッグデータ解析 〜 前編 〜
Sparkを用いたビッグデータ解析 〜 前編 〜
 
解説: a semantic approach to recommending text advertisements for images
解説: a semantic approach to recommending text advertisements for images解説: a semantic approach to recommending text advertisements for images
解説: a semantic approach to recommending text advertisements for images
 

あなたのScalaを爆速にする7つの方法(日本語版)