현재 선택된 답변으로 인해 많은 비용이 드는 정규 표현식 작업에 대한 우려를 확인하는 성능 벤치 마크를 통한 주요 답변 평가
제공된 답변은 3 가지 주요 스타일로 제공됩니다 (JavaScript 답변을 무시하고;)).
- String.replace (charsToDelete, "")를 사용하십시오. 후드 아래에서 정규 표현식을 사용합니다.
- Lambda 사용
- 간단한 Java 구현 사용
코드 크기 측면에서 String.replace가 가장 간결합니다. 간단한 Java 구현은 Lambda보다 약간 작고 깨끗합니다 (IMHO) (잘못하지 마십시오-Lambdas를 적절한 곳에서 자주 사용합니다)
실행 속도는 가장 빠르거나 느리게 진행되었습니다. 간단한 Java 구현, Lambda 및 String.replace () (정규식 호출).
가장 빠른 구현은 StringBuilder 버퍼를 가능한 최대 결과 길이에 미리 할당 한 다음 "chars to delete"문자열에없는 문자를 버퍼에 추가하기 위해 조정 된 간단한 Java 구현이었습니다. 이렇게하면 문자열> 16 자 길이 (StringBuilder의 기본 할당)에서 발생하는 재 할당을 피할 수 있으며 발생하는 문자열의 복사본에서 문자를 삭제하는 "슬라이드 왼쪽"성능 적중을 피할 수 있습니다. Lambda 구현입니다.
아래 코드는 간단한 벤치 마크 테스트를 실행하여 각 구현을 1,000,000 회 실행하고 경과 시간을 기록합니다.
정확한 결과는 각 실행마다 다르지만 성능 순서는 변경되지 않습니다.
Start simple Java implementation
Time: 157 ms
Start Lambda implementation
Time: 253 ms
Start String.replace implementation
Time: 634 ms
Lambda 구현 (Kaplan의 답변에서 복사 한대로)은 삭제중인 문자의 오른쪽에있는 모든 문자 중 "하나씩 왼쪽으로 이동"을 수행하므로 속도가 느려질 수 있습니다. 삭제가 필요한 문자가 많은 긴 문자열의 경우 분명히 나빠질 수 있습니다. 또한 Lambda 구현 자체에 약간의 오버 헤드가있을 수 있습니다.
String.replace 구현은 정규식을 사용하며 각 호출에서 정규식 "컴파일"을 수행합니다. 이것의 최적화는 정규 표현식을 직접 사용하고 매번 컴파일하는 비용을 피하기 위해 컴파일 된 패턴을 캐시하는 것입니다.
package com.sample;
import java.util.function.BiFunction;
import java.util.stream.IntStream;
public class Main {
static public String deleteCharsSimple(String fromString, String charsToDelete)
{
StringBuilder buf = new StringBuilder(fromString.length()); // Preallocate to max possible result length
for(int i = 0; i < fromString.length(); i++)
if (charsToDelete.indexOf(fromString.charAt(i)) < 0)
buf.append(fromString.charAt(i)); // char not in chars to delete so add it
return buf.toString();
}
static public String deleteCharsLambda(String fromString1, String charsToDelete)
{
BiFunction<String, String, String> deleteChars = (fromString, chars) -> {
StringBuilder buf = new StringBuilder(fromString);
IntStream.range(0, buf.length()).forEach(i -> {
while (i < buf.length() && chars.indexOf(buf.charAt(i)) >= 0)
buf.deleteCharAt(i);
});
return (buf.toString());
};
return deleteChars.apply(fromString1, charsToDelete);
}
static public String deleteCharsReplace(String fromString, String charsToDelete)
{
return fromString.replace(charsToDelete, "");
}
public static void main(String[] args)
{
String str = "XXXTextX XXto modifyX";
String charsToDelete = "X"; // Should only be one char as per OP's requirement
long start, end;
System.out.println("Start simple");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++)
deleteCharsSimple(str, charsToDelete);
end = System.currentTimeMillis();
System.out.println("Time: " + (end - start));
System.out.println("Start lambda");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++)
deleteCharsLambda(str, charsToDelete);
end = System.currentTimeMillis();
System.out.println("Time: " + (end - start));
System.out.println("Start replace");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++)
deleteCharsReplace(str, charsToDelete);
end = System.currentTimeMillis();
System.out.println("Time: " + (end - start));
}
}