카테고리 없음

[java] 긴 StringTokenizer에 대한 Java 성능 문제

행복을전해요 2020. 12. 10. 00:50

First of all, thanks for your opinions. During last weekend I have run stress test with real data using a revised program and so happy that my problem is solved (Many thanks to A.J. ^_^ ). I would like to share my findings.

After studying the example mentioned by A.J., I have run some test program to read and process data using StringTokenizer and "indexOf" (Regex is even worst compared to StringTokenizer in my situation). My test program would count how many mini second is needed to process 24 messages (~12000 tokens each).

StringTokenizer need ~2700ms to complete, and "indexOf" only take ~210ms!

I've then revised my program like this (with minimum changes) and tested with real volume during last weekend:

Original program:

public class MsgProcessor {
    //Some other definition and methods ...
    
        public void processMessage (String msg) 
            {
                    //...
                    
                            StringTokenizer token = new StringTokenizer(msg, FieldSeparator);
                                    while (token.hasMoreTokens()) {
                                                my_data = token.nextToken();
                                                            // peformance different action base on token read
                                                                    }
                                                                        }
                                                                        }
                                                                        

And here is updated program using "indexOf":

public class MsgProcessor {
    //Some other definition and methods ...
        private int tokenStart=0;
            private int tokenEnd=0;
            
                public void processMessage (String msg) 
                    {
                            //...
                                    tokenStart=0;
                                            tokenEnd=0;
                                            
                                                    while (isReadingData) {
                                                                my_data = getToken(msg);
                                                                            if (my_data == null)
                                                                                            break;
                                                                                                        // peformance different action base on token read ...
                                                                                                                }
                                                                                                                    }
                                                                                                                    
                                                                                                                        private String getToken (String msg)
                                                                                                                            {
                                                                                                                                    String result = null;
                                                                                                                                            if ((tokenEnd = msg.indexOf(FieldSeparator, tokenStart)) >= 0) {
                                                                                                                                                        result = msg.substring(tokenStart, tokenEnd);
                                                                                                                                                                    tokenStart = tokenEnd + 1;
                                                                                                                                                                            }
                                                                                                                                                                                    return result;
                                                                                                                                                                                        }
                                                                                                                                                                                        }
                                                                                                                                                                                        
  • 원래 토큰에는 "null"데이터가 없습니다. FieldSeparator가 없으면 "getToken (msg)"은 null을 반환합니다 ( "no more token"에 대한 신호로).
-------------------

StringTokenizer java doc 에 따라 StringTokenizer 사용을 권장하지 않습니다 . 더 이상 사용되지 않으므로 사용할 수 있습니다. 권장하지 않습니다. 여기에 쓰여진 내용이 있습니다.

"StringTokenizer는 새로운 코드에서는 사용을 권장하지 않지만 호환성을 위해 유지되는 레거시 클래스입니다.이 기능을 원하는 사람은 대신 String의 split 메소드 또는 java.util.regex 패키지를 사용하는 것이 좋습니다."

다음 게시물을 확인하십시오. 그것은 당신이하려는 것과 똑같은 일을하는 다양한 방법의 아주 좋은 예를 가지고 있습니다.

stringtokenizer-class-vs-split-method-in-java 성능

거기에 제공된 샘플을 시도하고 가장 적합한 것이 무엇인지 확인할 수 있습니다.

-------------------

대신 최신 스캐너 클래스를 사용해 보지 않겠습니까? 스캐너는 스트림과 파일을 사용하여 구성 할 수 있습니다. 그래도 이전 StringTokenizer보다 효율적인지 확실하지 않습니다.



출처
https://stackoverflow.com/questions/7414978