2010-04-06 6 views
2

큰 파일을 많이 사용하여 읽고 처리하고 SolrEmbeddedServer (http://lucene.apache.org/solr/)에게 넘겨주는 Java 응용 프로그램이 있습니다.자바 탈출 HTML - 문자열 바꾸기 천천히?

private String htmlEscape(String input) 
{ 
    return input.replace("&", "&amp;").replace(">", "&gt;").replace("<", "&lt;") 
     .replace("'", "&apos;").replaceAll("\"", "&quot;"); 
} 

응용 프로그램을 프로파일 링하는 동안이 프로그램이이 기능에, 47 %의 총에 교체, 11 %에서를 시간의 약 58 %를 지출 : 기능의

하나는 기본 HTML 회피를하지 모두 다 바꿔. 이제

, 자바는 천천히, 교체 또는 내가 옳은 길을 그리고 난이 프로그램은 내 코드에 충분한 자바에서의 병목 현상을 가지고하지 효율적으로 고려해야한다? (아니면 내가 잘못 바꾸 었습니까?)

미리 감사드립니다! 당신이 commons-lang에서 StringEscapeUtils.escapeHtml(input)을 사용할 수 있습니다 HTML 회피를 들어

답변

8

. 이것은 아마도 더 효율적인 방법으로 구현 될 것입니다.

+1

공유지 - 랭 (당신이이 ASF2.0 라이센스이기 때문에 법적으로 그것을 할 수 있습니다)를하지 않는 한 commons-lang이 제공하는 추가 메서드 및 도우미 클래스가 필요합니다. 단일 메소드에 대한 완전히 새로운 종속성을 갖는 것은 좋지 않습니다. – Esko

+0

예.하지만 commons-lang은 대부분의 응용 프로그램에서 유용 할 수있는 많은 메소드를 가지고 있으며 작성자는 해당 메소드가 존재 하는지를 모르고 다시 작성합니다. – Bozho

+0

감사합니다. 아마도 유용 할 것입니다. 내가 잘못 본 것이 아니라면, 프로젝트는 이미 아파치 공유를 Solr에 대한 의존성으로 사용합니다. 나는 그것을 살펴볼 것이다 : – cpf

3

확실히 많은 대체 작업을 수행하는 가장 효율적인 방법은 아닙니다. 문자열은 불변이므로, 각각의 .replace()는 새로운 String 객체의 생성을 유도합니다. 예를 들어,이 함수를 호출 할 때마다 6 개의 String 객체가 임시로 생성됩니다.

예제를 보면 가장 간단한 해결책은 HTML 엔터티 인코딩에 기존 라이브러리 함수를 사용하는 것입니다. Apache commons StringEscapeUtils이 하나의 옵션입니다. 또 하나는

1

Apache Commons LangStringEscapeUtils 클래스에 매우 효율적인 escapeHtml 메소드를 가지고 있습니다.

그것은 그것에 대해 매우 똑똑하고, 당신이 설명하는 방법으로 문자열 대체를 사용하지 않지만, 그들을 발견으로 적절한 엔티티 문자를 대체 문자를 통해 대신 반복.

나는 편리한 어떤 기준을 가지고 있지 않지만,이 물건은 코드의 임계 경로에있는 경우,이 기성 빠른 솔루션을 사용하는 비제 것입니다.

0

String.replace의 일반적인 알고리즘은 약간 복잡하지만, 그렇게 나쁘지 않을 것이다. 코드를 보면 실제로는 정규식을 사용하여 구현되므로 빠르지는 않습니다.

분명히 문자 단위로 반복하여 훨씬 빠른 코드를 작성할 수 있습니다. 아마도 정확한 길이를 먼저 알아낼 수 있습니다.

당신은 [ -~] 이외의 문자를 처리하는 방법을 고려할 수 있습니다

. 이미 기능을 구현 한 라이브러리를 사용할 수도 있습니다.

1

replace를 호출 할 때마다 새 String이 반환됩니다. 이 함수를 호출 할 때마다, 즉시 파기 될 문자열의 4 개의 사본을 본질적으로 작성하고 있습니다. 입력 값이 충분히 크면 낭비가 될 수 있습니다.

내가 대신 (각 시간 문자열을 스캔 할 필요가있는) N replace 작업을 수행하는, 한 번만 목록 검색 있도록 알고리즘을 수정 제안 :

//psuedocode 
Map<Char, String> replacements = new HashMap<String, String>(); 
replacements.put("&", "&amp;"); 
replacements.put(">", "&gt;"); 
... 
private String htmlEscape(String input) { 
    StringBuilder sb = new StringBuilder(input.length()); 
    for (char c: sb.toCharArray()) { 
    if (replacements.containsKey(c)) { 
     sb.append(replacements.get(c)); 
    else { 
     sb.append(c); 
    } 
    return sb.toString(); 
} 
+0

나는 이미 구현을 변경하여 문자열에 특정 문자가 있는지를 확인했다. if가 더 빠르다 고 기대하면서 ... (아직 결과가 없지만 아마도 다른 사람들이 제안한대로 StringEscapeUtils를 사용할 것입니다.) – cpf

0

일반 사용자의 경우 Html 이스케이프 필드에 새 플레이어가 있습니다 (unbescape).

HTML 코드에 언 이스케이프 작업은 다음과 같이 수행 할 수 있습니다

이 가
final String unescapedText = HtmlEscape.unescapeHtml(escapedText); 
내가에서 대신 하나의 방법을 복사 좋을 것