Evaluasi jawaban utama dengan tolok ukur kinerja yang menegaskan kekhawatiran bahwa jawaban yang dipilih saat ini membuat operasi regex mahal di bawah tenda
Sampai saat ini jawaban yang diberikan datang dalam 3 gaya utama (mengabaikan jawaban JavaScript;)):
- Gunakan String.replace (charsToDelete, ""); yang menggunakan regex di bawah tenda
- Gunakan Lambda
- Gunakan implementasi Java sederhana
Dalam hal ukuran kode jelas String.replace adalah yang paling singkat. Implementasi Java sederhana sedikit lebih kecil dan lebih bersih (IMHO) daripada Lambda (jangan salah paham - Saya sering menggunakan Lambdas jika sesuai)
Kecepatan eksekusi adalah, dalam urutan tercepat ke paling lambat: implementasi Java sederhana, Lambda dan kemudian String.replace () (yang memanggil regex).
Sejauh ini, implementasi tercepat adalah implementasi Java sederhana yang disetel sehingga mengalokasi buffer StringBuilder ke panjang hasil maksimal yang mungkin dan kemudian hanya menambahkan karakter ke buffer yang tidak ada dalam string "karakter yang akan dihapus". Ini menghindari setiap realokasi yang akan terjadi untuk panjang Strings> 16 chars (alokasi default untuk StringBuilder) dan menghindari hit kinerja "slide kiri" untuk menghapus karakter dari salinan string yang terjadi adalah implementasi Lambda.
Kode di bawah ini menjalankan tes benchmark sederhana, menjalankan setiap implementasi 1.000.000 kali dan mencatat waktu yang berlalu.
Hasil yang tepat bervariasi setiap kali dijalankan tetapi urutan kinerja tidak pernah berubah:
Start simple Java implementation
Time: 157 ms
Start Lambda implementation
Time: 253 ms
Start String.replace implementation
Time: 634 ms
Implementasi Lambda (seperti yang disalin dari jawaban Kaplan) mungkin lebih lambat karena melakukan "pergeseran ke kiri oleh satu" dari semua karakter di sebelah kanan karakter yang dihapus. Ini jelas akan menjadi lebih buruk untuk string yang lebih panjang dengan banyak karakter yang membutuhkan penghapusan. Juga mungkin ada beberapa overhead dalam implementasi Lambda itu sendiri.
Implementasi String.replace, menggunakan regex dan melakukan regex "kompilasi" pada setiap panggilan. Optimasi ini akan menggunakan regex secara langsung dan cache pola yang dikompilasi untuk menghindari biaya kompilasi setiap kali.
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));
}
}