2014-07-25 30 views
7

Thực hiện thử nghiệm hiệu năng dịch vụ REST của Java Tôi thấy một mẫu không mong đợi: một phương thức tạo và trả về luôn luôn cùng một đối tượng giá trị trong mỗi lời gọi chạy nhanh hơn phiên bản khác chỉ trả về đối tượng giá trị được lưu trữ trong một lớp hoặc trường đối tượng.Tối ưu hóa JVM nào đang gây ra các kết quả hiệu suất này?

Code:

@POST @Path("inline") public Response inline(String s) { 
    return Response.status(Status.CREATED).build(); 
}  

private static final Response RESP = Response.status(Status.CREATED).build(); 
@POST @Path("staticfield") public Response static(String s) { 
    return RESP; 
} 

private final Response resp = Response.status(Status.CREATED).build(); 
@POST @Path("field") public Response field(String s) { 
    return resp; 
} 

đang Byte:

  • Inline (nhanh hơn): getstatic, invokestatic, invokevirtual, areturn
  • tĩnh nộp (chậm hơn): getstatic, areturn
  • Trường đối tượng (chậm hơn): aload, getfield, areturn

Performance (sử dụng Apache AB, chủ đề duy nhất, một số chạy với kết quả phù hợp):

  • Inline: 17.078,29 [#/sec] (trung bình)
  • lĩnh vực tĩnh: 5242,64 [#/sec] (trung bình)
  • lĩnh vực Object: 5417,40 [#/sec] (trung bình)

Môi trường: RHEL6 + JDK Oracle 1.7.0_60-b19 64bits

Có khả năng JVM đã tối ưu hóa phiên bản nội tuyến bằng mã gốc, nhưng không bao giờ xem xét tối ưu hóa hai mã kia vì chúng đã khá nhỏ?

+0

Tôi nghĩ rằng rất có thể một điều gì đó không hoạt động theo cách bạn nghĩ, bên ngoài mã trên. –

+0

"Trả về luôn luôn cùng một đối tượng giá trị" ... Có lẽ lớp REST biết rằng kết quả có thể được lưu trữ sau đó? –

+1

Đăng điểm chuẩn hoàn chỉnh. Chỉ khi đó chúng ta mới có thể tìm hiểu những gì đang xảy ra. – tmyklebu

Trả lời

3

Như đã nêu trong các nhận xét, rất khó để nói mà không thực sự nhìn vào hội đồng. Như năm nay đang sử dụng một khung công tác REST, tôi giả định tuy nhiên đó sẽ là khó khăn để nói từ hội đồng như có khá nhiều mã để đọc.

Thay vào đó, tôi muốn cung cấp cho bạn dự đoán được giáo dục bởi vì mã của bạn là một ví dụ điển hình về việc áp dụng costant folding. Khi một giá trị được gạch chân và không được đọc từ một trường, JVM có thể giả định một cách an toàn rằng giá trị này là không đổi. Khi JIT biên dịch phương thức, biểu thức liên tục do đó có thể được hợp nhất một cách an toàn với mã khung của bạn, điều có thể dẫn đến ít hơn JIT assebly và do đó cải thiện hiệu năng. Đối với giá trị trường, ngay cả giá trị trường final, không thể giả định giá trị không đổi vì giá trị trường có thể thay đổi. (Miễn là giá trị trường không phải là hằng số thời gian biên dịch, nguyên thủy hoặc hằng số String, được gạch chân javac.) Do đó, JVM có thể không cố định gấp giá trị.

Bạn có thể read more on constant folding trong hướng dẫn để các JMH nơi cần lưu ý:

Nếu JVM nhận ra là kết quả của việc tính toán là như nhau không có vấn đề gì, nó có thể khéo léo tối ưu hóa nó. Trong trường hợp của chúng ta, điều đó có nghĩa là chúng ta có thể di chuyển tính toán bên ngoài vòng lặp JMH bên trong. Điều này có thể được ngăn chặn bằng cách luôn luôn đọc các đầu vào từ trạng thái, tính toán kết quả dựa trên trạng thái đó, và tuân theo các quy tắc để ngăn chặn DCE.

Tôi hy vọng bạn đã sử dụng một khung như vậy. Nếu không, chỉ số hiệu suất của bạn có thể không hợp lệ.

Từ đọc mã byte, bạn thường không thể tìm hiểu nhiều về hiệu suất thời gian chạy vì trình biên dịch JIT có thể tinh chỉnh mã byte thành bất kỳ thứ gì trong quá trình tối ưu hóa. Bố cục mã byte chỉ nên quan trọng khi mã được giải thích mà thường không phải là trạng thái mà người ta sẽ đo lường hiệu suất là hiệu suất quan trọng, mã nóng luôn luôn được biên dịch JIT.

+0

Đây là câu trả lời hay nhất cho đến nay. Tôi đã lặp lại các bài kiểm tra hiệu suất mà không có khung công tác nào cả, và phương thức nội tuyến chậm hơn (các kết quả ngược lại). Vì vậy, bất kỳ việc tối ưu hóa nào đang xảy ra, nó chỉ xảy ra khi mã khung công tác đang hoạt động. Như bạn nói, thật khó để chắc chắn rằng đây là điều thực sự xảy ra trong trường hợp này, nhưng lời giải thích của bạn phù hợp với bối cảnh độc đáo và tôi đã học được điều gì đó mới mẻ hôm nay nhờ phản ứng của bạn. Cảm ơn! – Sebastian

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