검색결과 리스트
글
Groovy
(GString 너는 좀 다를 줄 알았는데..)
Benchmark
어느 분이 Groovy환경에서 다음 3가지 문자열 병합기능의 속도를 체크
해주셨다.
(REF: https://github.com/melix/benchmark-groovy-gstring)
GString
style interpolation+
style concatenation- usage of
StringBuilder
instead
결과!
Benchmark Mode Cnt Score Error Units
StringConcat.gstring thrpt 20 1623731.208 ± 59007.168 ops/s
StringConcat.gstringStatic thrpt 20 1606414.896 ± 25461.152 ops/s
StringConcat.simple thrpt 20 1500527.858 ± 11344.617 ops/s
StringConcat.simpleStatic thrpt 20 1374998.800 ± 42602.172 ops/s
StringConcat.stringBuilder thrpt 20 5061006.225 ± 223317.988 ops/s
StringConcat.stringBuilderStatic thrpt 20 7813080.536 ± 180546.293 ops/s
StringBuilder의 간단한 승리이다.. 육안으로 봐도
GString : "A"+"B" : StringBuilder
=
1623731 : 1500527 : 7813080
(몇배지..;;)
OPS란?
Operation per Second
로서 초당 수행 횟수, 단위 시간당 처리 횟수로 해석할 수 있다.
위는 특정 시간 단위에 실행한 횟수를 나타태며, Score 가 높은 것이 좋은 것
이다.
느낀점..
따져보니 그동안 나는 기능과 생산성 위주의 코딩을 많이 했었다.
문자열 조합시에 StringBuilder를 사용하라는 것은 Java를 교육하는 곳이나 책 등에서 빈번히 일러준다.
그런데도 나는 처음에 속도에 무뎌.. 그냥 잽싸게 + 를 사용하여 빠르게 코딩을 하는 성향
이 되었다.
이에대해 최근에 많이 후회하고 있다.
다양한 테스트를 겪고 객관적인 수치들을 보면서.. 뼈저리게 StringBuilder의 성능을 느낀다.
속도가 빠르다는 것은 단순히 우리가 시간을 절약한 것만을 의미 하진 않는다고 생각한다.
이것이 ECO .. 개발자가 행할 수 있는 친환경 패턴이자 지구를 사랑하는 길일 수도 있다...
사람들이 전기를 당연히 여기게 되는 경향이 있는데.. (이런쪽으로 가면 말이 길어지니.. 싹뚝!)
어쨌거나 저쨌거나
혹시 막 Java를 접하고 있다면 한마디 해주고싶다.
"그냥 무조건 StringBuilder에 버릇을 들여보세요."
설명
1. GString
Groovy를 사용할 때 Java와 최대한 호환이 가능
하지만 주의해야할 점
들이 몇몇 있다.
그중에 하나가 바로 String Literal
인데, Java에서 문자열 방식인 Double Quote
를 Groovy는 다르게 취급한다.
이를 GString
이라 부르며 해당 코드영역에서 사용가능한 변수를 $와 함께 내부에 적으면 자동으로 파싱
해주고 코드까지 가능하다.
"${name} Hi GString here."
"What is your id and code?.. ${nickName.trim().toUpperCase()} and ${getCode(id)}"
덕분에 유연하고 짧은 코드로 생산성이 올라가기도 한다.
Java에서 쓰는 일반적인 String Literal 방식을 사용하려면 Single Quote를 사용해야한다.
'Hi normal string'
2. "A"+"B"
일반적으로 사용하게 되는 문자열 조합방식이다.
"A" + "B"
되도록이면.. 아니 무조건 StringBuilder
또는 StringBuffer
(동기화Ver)를 사용하자.
설명은 아래에서 하는걸로 퉁치자..
3. StringBuilder
Java에서 String은 Immutable(불변성)의 성질
을 띄고 태어났다.
따라서 문자열은 내부적으로 값을 변경할 수 없게 되어있다.
때문에 위의 +
방식으로 문자열을 추가/조합 할 때는 새로운 객체를 생성하여 반환
한다.
따라서 속도가 느리다! (위의 Benchmark 결과에서 보듯이)
단순히 문자열이 잘 조합되고 있다는 허상을 버려야한다.
떄에 따라서는 이를 보완하는 StringBuilder와 StringBuffer를 사용하자!
때문에 성능이슈가 있다면.. 아니! 웬만하면 StringBuilder를 이용하여 문자열을 조합하는 것이 좋다!!!
4. 대안 on Groovy Code
그래도 Groovy인데 간단하게 문자를 합칠 방법이 없을까?!
Groovy에선 이런 방법도 있다.
'asdf' << "1234" << "0987"
이것은 StringBuffer다.. ㅎㅎ
아래 Test를 참고
@Test
void StringBufferLiteralTest (){
def ls = ''<<''
def lse = ''
//Check 1
assert ls instanceof StringBuffer
lse <<=''
assert lse instanceof StringBuffer
//Check 2
ls = ""<<''
assert ls instanceof StringBuffer
lse = ""
lse <<=''
assert lse instanceof StringBuffer
//Check 3
ls = ''<<""
assert ls instanceof StringBuffer
lse = ''
lse <<=""
assert lse instanceof StringBuffer
//Check 4
ls = ""<<""
assert ls instanceof StringBuffer
lse = ""
lse <<=""
assert lse instanceof StringBuffer
//Check 5
assert ('asdf' << "1234" << "0987") instanceof StringBuffer
}
따로 위 표현식 방법으로 Case를 추가
하여 내 컴퓨터에서 Benchmark를 해봤다.
Benchmark Mode Cnt Score Error Units
StringConcat.gstring thrpt 20 836615.413 ± 95390.742 ops/s
StringConcat.gstringStatic thrpt 20 841453.970 ± 66816.387 ops/s
StringConcat.simple thrpt 20 803602.209 ± 12869.850 ops/s
StringConcat.simpleStatic thrpt 20 736675.108 ± 17871.816 ops/s
StringConcat.stringBuilder thrpt 20 2973144.436 ± 74812.124 ops/s
StringConcat.stringBuilderStatic thrpt 20 3961921.314 ± 51815.580 ops/s
StringConcat.groovySBLiteral thrpt 20 2983610.561 ± 214896.367 ops/s
StringConcat.groovySBLiteralStatic thrpt 20 3914557.528 ± 309689.716 ops/s
위에 벤츠마크 검사해주신 분의 컴퓨터가 내 컴퓨터보다 좋다는 것을 알 수 있다... (싹뚝!)
가장 아래항목을 보자! groovySBLiteral
항목을 추가하였다.. 뭔 Error가 이리 많지.. 어쨌든 속도는 얼추 비슷하다만..
Reference - 참조
- Benchmark GString in Groovy: https://github.com/melix/benchmark-groovy-gstring
- IOPs vs OPS: https://m.blog.naver.com/PostView.nhn?blogId=mindgap&logNo=20161156066&categoryNo=1&proxyReferer=https%3A%2F%2Fwww.google.com%2F
- Performance when using StringBuilder/GString: http://groovy.329449.n5.nabble.com/Performance-when-using-StringBuilder-GString-td5717366.html
- groovy - Groovy文本 StringBuilder/StringBuffer: https://kb.kutu66.com/groovy/post_1312063
- Concatenate Strings in Groovy: https://dzone.com/articles/concatenate-strings-in-groovy
- Groovy literal StringBuilder/StringBuffer: https://stackoverflow.com/questions/1797478/groovy-literal-stringbuilder-stringbuffer/1797530
- StringBuffer, StringBuilder 가 String 보다 성능이 좋은 이유와 원리: https://cjh5414.github.io/why-StringBuffer-and-StringBuilder-are-better-than-String/
- StringBuilder와 StringBuffer의 차이점: https://c10106.tistory.com/2004
- Groovy literal StringBuilder/StringBuffer: https://stackoverflow.com/questions/1797478/groovy-literal-stringbuilder-stringbuffer/1797530
'LANGUAGE > Java & Groovy ' 카테고리의 다른 글
[Java] Java version switcher on Windows - 자바 버전 자주 바꿀 때!? (0) | 2020.04.15 |
---|---|
[Java] abstract class와 interface 차이점 (0) | 2020.03.15 |
[Java] public static void main(String[] args) 갖고 놀기 🤹♂️ (2) | 2020.03.14 |
[Groovy] try-with-resources ...... withCloseable{} 으로 대체한다? (0) | 2019.08.19 |
[Java] try-with-resources (가독성 높이기) (0) | 2019.08.19 |