2010-07-21 6 views
9

Tôi đã sử dụng newInstance() trong một loại khu vực quan trọng về hiệu suất của mã của tôi. Chữ ký phương pháp là:Hiệu suất của toán tử mới so với newInstance() trong Java

<T extends SomethingElse> T create(Class<T> clasz)

tôi vượt qua Something.class như là đối số, tôi nhận được một thể hiện của SomethingElse, tạo ra với newInstance().

Hôm nay tôi đã quay lại để xóa TODO hiệu suất này khỏi danh sách, vì vậy tôi đã chạy một vài thử nghiệm của nhà điều hành new so với newInstance(). Tôi đã rất ngạc nhiên với hình phạt hiệu suất của newInstance().

tôi đã viết một chút về nó, ở đây: http://biasedbit.com/new-vs-newinstance/

(. Xin lỗi về việc thúc đẩy tự ... Tôi muốn đặt văn bản ở đây, nhưng câu hỏi này sẽ phát triển ra khỏi tỷ lệ)

gì Tôi muốn biết lý do tại sao cờ -server cung cấp tăng hiệu suất như vậy khi số đối tượng được tạo tăng lên phần lớn và không cho giá trị "thấp", ví dụ: 100 hoặc 1000.

Tôi đã học bài học của mình toàn bộ điều phản xạ, đây chỉ là sự tò mò về các tối ưu hóa mà JVM thực hiện trong thời gian chạy, espec ially với cờ -server. Ngoài ra, nếu tôi làm điều gì sai trong bài kiểm tra, tôi sẽ đánh giá cao phản hồi của bạn!


Chỉnh sửa: Tôi đã thêm giai đoạn khởi động và kết quả hiện ổn định hơn. Cảm ơn các đầu vào!

+0

Liên kết bị hỏng:/ –

+0

Tôi đã khắc phục! – biasedbit

+0

Bài đăng trên blog đã [chuyển lại] (http://biasedbit.com/blog/new-vs-newinstance). –

Trả lời

5

Tôi đã học bài học của mình với toàn bộ điều phản xạ, đây chỉ là sự tò mò về tối ưu hóa JVM thực hiện trong thời gian chạy, đặc biệt là với cờ máy chủ. Ngoài ra, nếu tôi làm điều gì sai trong bài kiểm tra, tôi sẽ đánh giá cao phản hồi của bạn!

Trả lời phần thứ hai trước, mã của bạn dường như đang mắc lỗi cổ điển cho điểm chuẩn micro Java và không "làm nóng" JVM trước khi thực hiện các phép đo của bạn. Ứng dụng của bạn cần chạy phương thức thực hiện phép thử một vài lần, bỏ qua vài lần lặp đầu tiên ... ít nhất là cho đến khi các số ổn định. Lý do cho điều này là một JVM phải làm rất nhiều công việc để bắt đầu một ứng dụng; ví dụ. tải các lớp và (khi chúng đã chạy một vài lần) JIT biên dịch các phương thức mà thời gian ứng dụng đáng kể đang được chi tiêu.

Tôi nghĩ lý do "máy chủ" tạo sự khác biệt là (trong số những thứ khác), nó thay đổi các quy tắc xác định thời điểm biên dịch JIT. Giả định là cho một "máy chủ" nó là tốt hơn để JIT sớm hơn này cho khởi động chậm hơn nhưng thông lượng tốt hơn. (Ngược lại, một "client" được điều chỉnh để trì hoãn việc biên dịch JIT để người dùng nhận được một GUI làm việc sớm hơn.)

+0

Tôi đã thêm một vài lần lặp lại trước khi chạy thử nghiệm thực tế và tôi nhận được các con số tốt hơn, ổn định hơn. Với cờ máy chủ, newInstance() ổn định ở mức 2,5 ~ 2,9 lần chậm hơn so với mới (cả đối với 100 và đối tượng 1kk). Nếu không có máy chủ nó vẫn tăng cao gấp 8 ~ 9 lần đối với 100 vật thể lên đến 25 chậm hơn cho 1kk). Lời khuyên tuyệt vời! :) – biasedbit

+0

Một cách tốt hơn để làm ấm JVM đúng cách, là vượt qua các đối số dòng lệnh -XX: + PrintCompilation để làm cho JVM in ra tất cả các biên dịch JIT và tối ưu hóa khi nó thực hiện chúng. Sau đó, đảm bảo rằng không có bước biên dịch nào xảy ra trong quá trình chạy theo thời gian của bạn. – LordOfThePigs

+0

@LordOfThePigs - Tôi không đồng ý. Nói chung, cách tốt nhất là chạy một số lượng lớn các lần lặp (xen kẽ), ghi lại thời gian và loại bỏ những lần đầu bị bất thường. Sau đó, trung bình. Điều này sẽ chăm sóc các nguồn khác của vấn đề cũng như JITing. Cách tiếp cận '-XX: + PrintCompilation' chỉ giải quyết các dị thường JIT. –

1

Trong số những thứ khác, hồ sơ thu thập rác cho tùy chọn -server có các giá trị mặc định khác nhau survivor space sizing.

Khi đọc kỹ hơn, tôi thấy ví dụ của bạn là micro-benchmark và kết quả có thể phản trực giác. Ví dụ: trên nền tảng của tôi, các cuộc gọi lặp lại đến newInstance() được tối ưu hóa hiệu quả trong các lần chạy lặp lại, làm cho newInstance() xuất hiện nhanh hơn 12,5 lần so với new.

+0

Tôi chạy bằng -XX: + PrintGCDetails và tôi chỉ thấy 1 bộ sưu tập - toàn bộ bộ sưu tập mà tôi đã buộc giữa hai lần kiểm tra. Tôi đã đảm bảo cung cấp đủ bộ nhớ cho ứng dụng để nó không cần phải thay đổi kích thước hoặc thu thập (thực ra tôi cũng đang ngăn việc thay đổi kích thước bằng cách sử dụng cùng một -Xmx dưới dạng -Xms). Trong các điều kiện này, tôi tin GC không phải là yếu tố quyết định trong kết quả. – biasedbit

+0

@brunodecarvalho: Vâng, tôi hiểu ý của bạn là gì và tôi đã xây dựng ở trên. Bạn có thể cần phải viết lại điểm chuẩn của mình để có được kết quả có ý nghĩa. – trashgod

+0

Vâng, tôi đã sợ hiệu ứng siêu chuẩn ở đây. Tôi chỉ thêm cá thể mới vào mảng đối tượng đó với hy vọng rằng trình biên dịch sẽ không nhận ra đó là thao tác vô nghĩa và xóa toàn bộ vòng lặp. Tôi sẽ kiểm tra lại điều này bằng cách sử dụng hệ thống mà tôi sắp tối ưu hóa. Tuy nhiên, tôi thấy hơi lạ rằng newInstance() nhanh hơn mới. Nhìn qua nguồn của JDK, dường như có rất nhiều chi phí mà newInstance() đi qua và cái mới thì không. – biasedbit

1

IMHO hình phạt về hiệu suất đến từ cơ chế tải lớp. Trong trường hợp phản ánh tất cả các cơ chế bảo mật được sử dụng và do đó hình phạt tạo ra cao hơn. Trong trường hợp toán tử mới, các lớp đã được nạp trong máy ảo (được kiểm tra và chuẩn bị bởi trình nạp lớp mặc định) và sự khởi tạo thực tế là một quá trình giá rẻ. Tham số -server thực hiện rất nhiều tối ưu hóa JIT cho mã được sử dụng thường xuyên. Bạn có thể muốn thử nó cũng với tham số -batch sẽ thương mại tắt thời gian khởi động nhưng sau đó mã sẽ chạy nhanh hơn.

+0

Giải thích của bạn có ý nghĩa, vì tôi đã xem xét mã và tìm ra toàn bộ cơ chế bảo mật sẽ bổ sung thêm chi phí đáng kể. Tuy nhiên, cờ -batch dường như không hợp lệ. – biasedbit

+0

@brunodecarvalho: Bạn nói đúng! Cú pháp là -Xbatch không theo lô như tôi đã gõ. Để biết chi tiết, hãy xem: http://download.oracle.com/docs/cd/E17476_01/javase/1.4.2/docs/tooldocs/windows/java.html và http : //download.oracle.com/docs/cd/E17409_01/javase/6/docs/technotes/tools/windows/java.html –

+0

Dường như không có nhiều khác biệt. Tôi đã loại bỏ giai đoạn khởi động để xem liệu nó có ảnh hưởng đến kết quả hay không nhưng tôi nhận được khá nhiều giá trị giống với -Xbatch và không có. Tuy nhiên, đó là một lá cờ rất thú vị! – biasedbit