elasticsearch 벤치마크 툴인 Rally가 4월에 출시되었다.


https://www.elastic.co/kr/blog/announcing-rally-benchmarking-for-elasticsearch


https://github.com/elastic/rally



으와.. 프로파일링과 JIT 컴파일 수까지 표현해준다.


ES 성능 테스트할 때 좋을 것 같다. 




차트와 더 자세한 내용을 보려면 여기를 클릭한다.


https://benchmarks.elastic.co/index.html



https://benchmarks-old.elastic.co/index.html

Posted by '김용환'
,



일반적인 HTTP 성능 테스트를 진행할 때,

일반적인 벤치마크는 웹 서버에서 요청을 처리한 시간을 먼저 저장하고, 클라이언트로 전달되기 직전 시간(응답 시간) 사이의 경과된 시간을 측정한다. 하지만, 웹 서버는 서버에서의 지연 시간(전문용어 latency)만을 측정하지 그 이후는 측정되지 않는다. 


바로 이 문제를 조율된 누락 문제(coordinated omission)라 한다. 성능 벤치마크시 많이 간과하기도 한다. 백분위수가 높거나 TPS가 어이 없이 높다면 의심할 필요가 있다. 


괜찮은 벤치마크일수록 요청을 보낸 순간과 클라이언트에서 응답을 실제로 받는 순간 사이의 시간을 명확히 측정한다. 즉 좋은 HTTP 성능 벤치마크라면, 클라이언트에서 HTTP 요청의 응답을 제대로 받은 순간까지의 시간을 측정할 수 있을 것이다. 


(그래서 Load Runner가 대단한 툴이라 생각하고 있다..)



참고로 더 자세한 내용을 보기 원하면, 두 개의 링크를 참조한다.


https://www.quora.com/In-Java-what-is-Coordinated-Omission



특히 아래 링크는 공부하기 좋은 자료가 있다.


https://groups.google.com/forum/#!msg/mechanical-sympathy/icNZJejUHfE/BfDekfBEs_sJ





참고로,  조율된 누락 문제를 언급한 툴로 elasticsearch rally에 있었다. rally의 현재 이슈에 대해서 elasticsearch 블로그에서 잘 설명되어 있어서, 관련 내용을 살펴보는 것도 좋을 것 같다.


https://www.elastic.co/kr/blog/announcing-rally-benchmarking-for-elasticsearch




아래 이슈에서 열심히 토론 중이다.


https://github.com/elastic/rally/issues/64







Posted by '김용환'
,



scala의 println은 여러 줄을 출력할 수 있는 기능이 있다. 다른 언어에서는 """ 비슷한 multi line 개념이 있어서 참 좋았다. scala에 이 기능이 있어서 편리하다. 


예시 1 - """ """ 만 쓰면 그대로 공백이 나온다.

예시 2 -""" """에 stripMargin 메소드를 사용해서 공백을 정리한다.  (토큰은 디폴트로 | 이다.)

예시 3-stripMargin 메소드에 사용자 정의 토큰을 정리할 수 있다.

예시 4- new line을 empty string으로 치환할 수 있다.

예시 5 - "" 안에 expression을 사용할 수 있다. 


println {
s"""A is
not B"""
}
println

println {
s"""A is
|not B"""
.stripMargin
}
println

println {
s"""A is
@not B"""
.stripMargin('@')
}
println

println {
s"""A is
@not B"""
.stripMargin('@').replaceAll("\n", " ")
}
println

val commands = List("put", "get", "delete")
val number = 3
println {
s"""
|${commands.size}
|${commands.size / number} """
.stripMargin
}



결과



A is

          not B


A is

not B


A is

not B


A is not B



3

1        




Posted by '김용환'
,


튜플과 _1, _2와 match를 이용한 예시이다. 


튜플은 다양하게 생성할 수 있고, 내부 요소를 _1, _2로 만들 수 있다. 튜플의 개수에 따라 실제로 생성되는 클래스가 동적으로 생성된다. 2개의 요소를 가진 튜플은 scala.Tuple2 타입이다. 

tuple을 통해 타입과 값에 대한 match를 실행해봤고, 이를 더 응용해 메소드에서 match를 쓸 수 있도록 테스트했다.

val student = "Kyle" -> 22
// val student = ("Kyle", 22)
println(student._1, student._2)
println(student.getClass)

val result = student._1 match {
case "ABC" => "What?"
case s: String => "String"
}
println(result)
println(testMatch(student._1))



testMatch 코드는 다음과 같다. string의 값을 case문으로 비교한다. 

def testMatch(str : String) = str match {
case "Kyle" => "KK"
case _ => "Aha"
}



결과는 다음과 같다. 


(Kyle,22)

class scala.Tuple2

String

KK


Posted by '김용환'
,


스칼라의 콜렉션 객체에서 foldLeft을 많이 사용한다. 왼쪽 항부터 마지막 항까지 계산되는 것을 의미한다. 

리스트의 값을 왼쪽에서 오른쪽으로 계산한다. 0(초기값) + 3 + 6 + 9  = 18이 예상된다.

val list : List[Int] = List(3, 6, 9)
println(list.foldLeft(0) ((x, y) => x + y))

결과는 다음과 같다.


18



이 코드는 조금 아래처럼 잼나게 _+_로 바꿔 쓸 수 있다.  결과는 동일하다. 


val list : List[Int] = List(3, 6, 9)
println(list.foldLeft(0) (_+_))

동작이 어떻게 되는 지 궁금하다면 다음처럼 디버깅하듯이 코딩할 수 있다.

val list : List[Int] = List(3, 6, 9)
println(list.foldLeft(0) { (x : Int, y : Int) => println("x:"+ x + ",y:"+ y); x + y })


결과는 다음과 같다.


x:0,y:3

x:3,y:6

x:9,y:9

18








이제, foldRight 메소드를 사용한다.


val list : List[Int] = List(3, 6, 9)

println(list.foldRight(0) ((x, y) => x - y))


 


결과를 0으로 생각할 수 있겠지만, 사실 결과는 6이 출력된다.




출력할 수 있도록 println을 사용해본다.

val list : List[Int] = List(3, 6, 9)
println(list.foldRight(0) { (x : Int, y : Int)
=> println("x:"+ x + ",y:"+ y); x - y })


결과는 다음과 같다. 3 - (-3) = 6 이 된다. 


x:9,y:0

x:6,y:9

x:3,y:-3

6






문자열도 foldLeft도 사용할 수 있다. 


val list : List[String] = List("aaa", "bbb", "ccc")
list.foldLeft("xxx") { (x : String, y : String)
=> println("x: " + x + " y: " + y) ; x + ":" + y}


출력은 다음과 같다.


x: xxx y: aaa

x: xxx:aaa y: bbb

x: xxx:aaa:bbb y: ccc

Posted by '김용환'
,



naive에 대한 좋은 설명이 있는 싸이트


http://www.ohmynews.com/NWS_Web/View/at_pg.aspx?CNTN_CD=A0001330871


말뜻 그대로라면 '소박'이나 '순진'이나 '천진난만'이라는 '나이브'는 '해맑은'이나 '티없는'으로 적바림해야 알맞습니다. 착하거나 맑거나 티없는 사람은 때때로 '고지식하'거나 '어리석'은 짓에 휘말려들곤 하니 '철없다-바보스럽다-꾸밈없다' 같은 낱말을 넣어 볼 수 있습니다.


Posted by '김용환'
,


Stream 객체를 써서 List의 요소를 반복하고 싶다면, Stream.continually(리스트).take() 메소드를 사용한다.


val list : List[String] = List("aaa", "bbb", "ccc")
println(Stream.continually(list).take(10).flatten.toList)



결과


List(aaa, bbb, ccc, aaa, bbb, ccc, aaa, bbb, ccc, aaa, bbb, ccc, aaa, bbb, ccc, aaa, bbb, ccc, aaa, bbb, ccc, aaa, bbb, ccc, aaa, bbb, ccc, aaa, bbb, ccc)







주의할 점은 다음 코드는 Stream(aaa, ?) 타입을 리턴하게 되니. 값을 확인할 수 없다.


println(Stream.continually(list).take(10).flatten)



scala> Stream.continually(list.toStream).take(10).flatten

res5: scala.collection.immutable.Stream[String] = Stream(aaa, ?)




Posted by '김용환'
,



JIT compiler compiles bytecode on-the-fly.

JIT 컴파일러는 바이트 코드를 즉시 반영할 수 있도록 컴파일한다. 



바로 반영할 수 있는 바이트코드 컴파일러

An On-the-fly Bytecode compiler 



바로 지원

on-the-fly support



서버에서 응답 결과를 압축(gzip)해서 클라이언트로 전송

on-the-fly compression



Posted by '김용환'
,



package object 에 대한 설명은 다음과 같다.

http://www.scala-lang.org/docu/files/packageobjects/packageobjects.html



com/google/utility 디렉토리에 package.scala를 생성하고 다음 코드를 저장한다.

scala에 패키지용 utility 처럼 쓸 수 있는 클래스와 같다. 


package com.google

import org.slf4s.Logging

package object utility extends Logging {
def print(message : String): Unit = {
println(message)
}
}


com/google 디렉토리에 test.scala를 생성한다.


package com
package google

object test {
def main(args: Array[String]): Unit = {
utility.print("test")
}
}


실행 결과는 다음과 같다.


test 




참고로 같은 패키지에 존재하기 때문에 test 클래스는 다음처럼 사용할 수 있다.


package com
package google

object test {
def main(args: Array[String]): Unit = {
print("test")
}
}

또는


object test {
def main(args: Array[String]): Unit = {
print("test")
}
}


Posted by '김용환'
,