2018년 10월 19일 금요일

openJDK String 처리 속도 비교


JVM성능 측정에 여러가지 측면이 있겠으나 (collection object, network, thread....)
젤 만만 한게  요즘은 XML에 JSON이 대세이므로 Sting 연산이 많이 쓰이기 때문에 그냥 이걸루 비교를 해봤다

결과값은 절대적이지 않고  내용에 책임 못 진다.
그냥 참고만 하고 비슷한 테스트할때 이해하는데 사용하시라

Server : Physical Xeon 40Core
MEM : 64G
Heap : 4G  (TEST를 위해 작게 잡고 동일한 환경으로 테스트)

TEST Tool : JMH http://openjdk.java.net/projects/code-tools/jmh/
TEST Sample code : http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/  (이건 다 돌리면 10시간 걸린다... 회사내부에서 볼 자료라 오픈하기 뭐해서 안올릴란다)

TEST String code :.... 걍 만들어 올리기도 구찮음...는 아니고...이놈에 블로그스팟 넘해... 에디터에 무슨 박스 하나가 없어요.... {code} 이런것 까지 원하지도 않아 그냥 좀 표같은거라도 좀 편집 할 수 있게 해주면 안되나!!!!  맨날 HTML Code수정해야 겠냐...미치것내
정말 집에 NAS에 워드프레스를 깔던가 해야지 원....

어디선가 배껴온 소스에 값만 바꿔 쓴다.(어딘지 출처가 기억안난다 ㅋㅋ)
some more data 라를 문자를 StringBuilder append로 1만번  String  +연산으로 1만번 하는 코드를
워밍업 5회 후  10회의 테스트를 하고 처리시간을 평균낸 데이터를 그래프에 사용했다
가끔 GC가 떠서 성능이 개판난 데이터는 3회 정도 해서 젤 높은 값을 빼고 다시 평균을 잡았다.



cat StringConcatenationBenchmark.java

package org.samples;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Measurement(batchSize = 10000, iterations = 10)
@Warmup(batchSize = 10000, iterations = 5)
@Fork(1)
public class StringConcatenationBenchmark {
    private static final String S = "some more data";
    private static final int maxLen = S.length()*100000;

    private String string;

    private StringBuilder stringBuilder;

    @Setup(Level.Iteration)
    public void setup() {
        string = "";
        stringBuilder = new StringBuilder();
    }

    @Benchmark
    public void stringConcatenation() {
        if(string.length() >= maxLen) string = "";
        string += S;
    }

    @Benchmark
    public void stringBuilderConcatenation() {
        if(stringBuilder.length() >= maxLen) stringBuilder = new StringBuilder();
        stringBuilder.append(S);
    }

}



시나리오
CentOS6, 7 2개 OS에서
oracle, adopt, redhat yum, Azul zulu 를 동일한 환경으로 수행해서 수행시간을 구했다
당연히 빠를 수록 좋은 거고 결과를 보면 편차가 100microsec 안에서 대동소이 하기 때문에 뭐 크게 이상하다고 할 부분이 없었다
다만
CentOS6 에서 adopt와 Zulu의 경우 CPI  (Cycles per instruction-명령어 수행시 사용된 CPU클럭의 수)가 좀 더 높은데 같은 작업 처리시 처리 능력의 문제라기 보다는 CPU를 좀 더 사용할 것이라는 추측이 가능하다.
아무래도 oracle 과 readhat은 나름 openjdk source를 변경하는 작업이 있겠고
openjdk 소스와 동일하게 빌드만(? 그런걸로 알고 있다) 구성한 adoptOpenjdk와 Zulu의 경우 비슷한 증상(CPI높음)이 보였다

하지만 CentOS7 (kernel 3.x)에서는 편차 없이 다들 잘 동작 하는 것을 알 수 있었다.


거진 비슷비슷 100microsec 편차



StringBuilder와 String+연산의 속도 차이를 보라....어마어마 하다
1,000 vs 100,000 이다
아직도 str+=str  하는 친구들은 X잡고 반성하자....

여기서도 별 편차 없다. JIT에서 최적화 되지 못하므로
CPI는 워낙 엉망으로 나와서 참고가 않된다

솔직히 개인생각에
JVM Crash만 나지 않는다면 뭘 쓰던 무슨상관이냐 싶으다
어짜피 TCK pass했으면 기본적인 게런티는 되는거고....
여하간 짧게 끝내본다.

댓글 없음:

댓글 쓰기

본 블로그의 댓글은 검토후 등록됩니다.