4. Thử nghiệm
String a = "";
// StringBuilder a1 = new StringBuilder("");
for (Long i = 0L; i < 100000L; i++) {
a = a.concat(i.toString()); // take 6400ms
// a += b; // take 22340s
// a1.append(i) // 19ms
}
Khi làm việc với chuỗi trong Java chúng ta có 3 options: String, StringBuilder, StringBuffer.
Để làm rõ hơn chúng ta cùng tìm hiểu cách chúng hoạt động khi cộng chuỗi.
Ta xét ví dụ sau:
String query = "SELECT username FROM" + " Users " + " WHERE 1 = 1";
query += " AND age > 20";
query += " AND gender = 1";
query = query.concat(" AND is_delete = 0");
String query = "SELECT username FROM" + " Users " + " WHERE 1 = 1";
Với câu lệnh này thì Java compiler sẽ convert chúng thành:
String query = (new StringBuilder()).append("SELECT username FROM")
.append(" Users")
.append(" WHERE 1 = 1").toString();
Thay vì việc tạo ra nhiều ô chỉ nhớ khác nhau để lưu các String và sau đó cộng chúng lại với nhau. Compiler của Java đã làm việc rất hiệu quả để tối ưu được bộ nhớ.
Note: Có thể dùng + để concat các giá trị primitive khác với String. Compiler cũng sẽ convert chúng như trên.
String info = "I am " + 25 + "years old";
query += " AND age > 20";
query += " AND gender = 1";
Java compiler sẽ convert chúng thành:
StringBuilder tmp;
tmp = new StringBuilder();
tmp.append(query);
tmp.append(" AND age > 20");
query = tmp.toString();
tmp = new StringBuilder();
tmp.append(query);
tmp.append(" AND gender = 1");
query = tmp.toString();
Như vậy sẽ tạo ra rất nhiều instance của StringBuilder. Khi số lượng chuỗi cộng ít thì có thể không vấn đề. Nhưng khi số lượng lớn nên sẽ rất ảnh hưởng đến performance. (Xem kết quả thực nghiệm phía dưới)
query = query.concat(" AND is_delete = 0");
Vì concat() của String trong Java được thực hiện bằng cách:
Note: Với cách dùng concat() gây tốn bộ nhớ và performance khi phải tạo 1 ô nhớ mới.
=> StringBuilder/StringBuffer khi cộng chuỗi sẽ tốt hơn String rất nhiều.
String a = "";
// StringBuilder a1 = new StringBuilder("");
for (Long i = 0L; i < 100000L; i++) {
a = a.concat(i.toString()); // take 6400ms
// a += b; // take 22340s
// a1.append(i) // 19ms
}