2014-06-05 21 views
13

Tôi đã trải qua các tính năng mới được thêm vào được giới thiệu trong Java-8. Một tính năng đơn giản mới được thêm vào lớp Chuỗi là hấp dẫn đối với tôi - đó là String Join method.Java 8: Hoạt động nối chuỗi có tác động hiệu suất đáng kể

Ví dụ:

String.join(" ", "AZY","BAX"); // returns AZY BAX 

Đối với sự tò mò, tôi đã kiểm tra việc thực hiện (thời gian thực hiện) của tính năng này bằng cách viết một mã java đơn giản

public static void main(String[] args) { 
    long start = System.nanoTime(); 
    String abc= String.join(" ,"AZY","BAX" … // joining 1000 words of size 3 char; 
    long diff = System.nanoTime() - start; 
    System.out.println(" Java 8 String Join " + diff); 

    start = System.nanoTime(); 
    abc= "AZY"+"BAX"+"CBA"+ … // adding 1000 word of size 3 char; 
    diff = System.nanoTime() - start; 
    System.out.println(" Tranditional " + diff); 

    start = System.nanoTime(); 
    new StringBuilder().append("AZY").append("BAX").appe… // appending 1000 word of size 3 char; 
    diff = System.nanoTime() - start; 
    System.out.println(" String Builder Append " + diff); 

} 

Kết quả không phải là quá thú vị đối với tôi (thời gian trong neno giây)

Java 8 String Join  1340114 
Tranditional    59785 
String Builder Append 102807 

Sự phức tạp là o (n) - thực tế là (n * Kích thước của ind chiều dài phần tử ividual)

Các biện pháp hiệu suất khác (bộ nhớ, vv) Tôi chưa đo.

Câu hỏi của tôi là:

  1. Có gì không ổn trong đo lường của tôi (phần lớn thời gian tôi tin vào những kẻ jdk)
  2. mục đích của việc thêm là gì “tham gia” API để lớp String
  3. Có phân tích hiệu suất nào cho Java 8 không có sẵn
+13

Viết điểm chuẩn chính xác trong Java không đơn giản như vậy bởi vì các thuật toán JIT và thu gom rác thải. Xem [Làm cách nào để viết một điểm chuẩn chính xác trong Java?] (Http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java). – Jesper

+0

Vì tò mò, tại sao một người sử dụng phương pháp này thay vì '+'? – Djon

+11

Ngoài ra, ghép chuỗi ký tự chuỗi được thực hiện tại thời gian biên dịch, vì vậy bạn không thực sự kiểm tra bất cứ điều gì trong thử nghiệm thứ hai. – Jesper

Trả lời

42

Điều đầu tiên trước tiên. Đây không phải là cách bạn vi phạm Java

Đọc How do I write a correct micro-benchmark in Java? trước tiên. Số của bạn hoàn toàn không liên quan, vì vậy, hãy bỏ qua chúng.

Nhìn vào ví dụ thứ hai:

abc= "AZY"+"BAX"+"CBA"+... 

Những trông giống như hằng số thời gian biên dịch đối với tôi. Điều này String sẽ được ghép nối tại thời gian biên dịch và sẽ không có gì để chuẩn. Đây là một so sánh vô ích vì toàn bộ điểm của StringBuilder hoặc String.join là ghép nối String s không phải là hằng số thời gian biên dịch.

Di chuyển lên so sánh StringBuilderString.join. Nhìn vào mã nguồn:

public static String join(CharSequence delimiter, CharSequence... elements) { 
    Objects.requireNonNull(delimiter); 
    Objects.requireNonNull(elements); 
    // Number of elements not likely worth Arrays.stream overhead. 
    StringJoiner joiner = new StringJoiner(delimiter); 
    for (CharSequence cs: elements) { 
     joiner.add(cs); 
    } 
    return joiner.toString(); 
} 

Điều này sử dụng StringJoiner. Một StringJoiner chỉ cần sử dụng một StringBuilder dưới mui xe, do đó, hai là tương đương.

Thường có nhiều thông tin hơn để xem ở mã hơn là thử và hiệu suất điểm chuẩn. Ngay cả khi bạn làm điểm chuẩn chính xác.

Cũng cần lưu ý rằng phương pháp đầu tiên của bạn, với join, tham gia 1000 String giây trên "" (dấu cách). Trong khi phương pháp StringBuilder của bạn chỉ cần nối chúng lại với nhau. Hai cái này không giống nhau.

Mấu chốt của phương pháp String.join là bạn có thể làm:

String.join(", ", "a", "b", "c") // result is "a, b, c" 

Với StringBuilder bạn sẽ phải thêm mã nhiều hơn nữa.

+0

Câu hỏi này không cố gắng t o Java chuẩn. nhưng để hiểu mục đích của API "tham gia". (Tôi nghĩ rằng nó rõ ràng từ các câu hỏi). Tôi vẫn không chắc chắn lý do tại sao chúng ta cần một API mà lặp lồng nhau (một trong String.jave- tham gia() phương pháp như bạn nói mà nội gọi phương thức append() của AbstractStringBuilder) thay vì sử dụng StringBuilder trực tiếp – dgm

+20

@dipankaj vì toàn bộ điểm của Java 8 là thêm các phương thức tránh lặp vòng lặp rõ ràng và sử dụng các mô hình chức năng hơn. 'String.join' được cho là một lối tắt cho' Stream.of (a, b, c) .collect (Collectors.joining()) '. Nếu bạn không thấy lợi ích của việc cho phép người dùng tham gia một 'Chuỗi' trong một dòng mã thay vì 4 thì không sử dụng nó ... –

+0

Trừ khi điều này được ghi lại, hành vi mong đợi, điều này sẽ phụ thuộc vào JVM. JVM bạn đã kéo cái này từ đâu? Tôi đã phần nào mong đợi nó để tổng hợp chiều dài của các chuỗi trong mảng và chỉ tạo mảng đích. Đặc biệt khi sử dụng một trình tạo như vậy có khả năng phân bổ các mảng nhiều lần nếu bạn đang xử lý số chuỗi mà OP đang xử lý ... –

Các vấn đề liên quan