*
역시 단순 루프에서는 i, j 방식이 월등하군요. =,=
귀찮지만 라이브러리에서는 i, j 써야할 듯 싶습니다.
JVM 자체가 펑셔널하지 않아서 언어로 극복하는데는 한계가 있는 듯.
printElapsedTime {
for(index <- 0 until Int.MaxValue) { }
} // 44,9xx
printElapsedTime {
var i = 0
while(i < Int.MaxValue) { i += 1 }
} // 1.4xx
*
Map 반복하는 여러가지 방식입니다
큰차이 없으나 사용편의성과 속도면에서 중간치기 for 가 괜찮아 보입니다.
val m = mutable.Map.empty[Int, Int]
(1 to 10000).foreach { it => m(it) = it }
def dumb(k: Int, v: Int) = k + v
printElapsedTime(10000) {
for((k, v) <- m) { dumb(k, v) }
} // 9,461
printElapsedTime(10000) {
m.foreach{ kv => dumb(kv._1, kv._2) }
} // 9,295
printElapsedTime(10000) {
m.foreach{ case(k, v) => dumb(k, v) }
} // 9,861
*
스트링 검색 루프입니다.
역시 i, j 의 완승. =,=
val s = "... big string ..."
val repeat = 1000000
def dumb(c: Char) = c
printElapsedTime(repeat) {
var i = 0
while (i < s.length) { dumb(s.charAt(i)); i += 1 }
} // 7,719
printElapsedTime(repeat) {
var i = 0
val len = s.length
while (i < len) { dumb(s.charAt(i)); i += 1 }
} // 5,776
printElapsedTime(repeat) {
for (ch <- s) { dumb(ch) }
} // 62,136
*
값에 따른 분기 처리입니다.
신기하게 if 가 match 보다 느립입니다. 몇 번을 해봤는데.
!= null 이 == null 보다 빠릅니다.
스칼라에서는 if 대신 가능하면 match 를 쓰는 것이
퍼포먼스나 미적인 면에서 모두 좋겠습니다. ^^
val msg = "hi"
val repeat = 300000000
def dumb(i: Int) = if (i % 2 == 0) msg else null
def dumb2(i: Int) = if (i % 2 == 0) Some(msg) else None
def noop1(msg: String) {}
def noop2 {}
printElapsedTime(repeat) { r =>
val s = dumb(r)
if (s != null) noop1(s) else noop2
} // 10,537
printElapsedTime(repeat) { r =>
val s = dumb(r)
if (s == null) noop2 else noop1(s)
} // 10,796
printElapsedTime(repeat) { r =>
dumb(r) match {
case s: String => noop1(s)
case null => noop2
}
} // 8,942
printElapsedTime(repeat) { r =>
dumb2(r) match {
case Some(s) => noop1(s)
case None => noop2
}
} // 10,473