1 Câu hỏi: Tối ưu hóa nhận các giá trị tham số

câu hỏi được tạo ra tại Wed, May 8, 2019 12:00 AM

Tôi muốn biết liệu có sự khác biệt nào về hiệu suất giữa hai cách nhận giá trị tham số này trong Java không:

Tùy chọn 1:

for(int i=0; i<1000; i++) {
    System.out.println(object.getName());
}

Tùy chọn 2:

String name = object.getName();
for(int i=0; i<1000; i++) {
   System.out.println(name);
}

Có thể chỉ với 1 thuộc tính (tên), tùy chọn 2 sẽ tốt hơn, nhưng, nếu tôi có 50 thuộc tính khác nhau thì sao? Tôi sẽ lãng phí bộ nhớ lưu trữ các biến đó.

Xin vui lòng, nghĩ lớn, trong một hệ thống khổng lồ với hàng tấn người dùng truy cập vào Ứng dụng Web.

    
0
  1. Lãng phí bộ nhớ sẽ rất nhỏ, giống như mức tăng hiệu suất. Điều này được gọi là tối ưu hóa vi mô và bạn không nên tính đến nó khi phát triển (hoặc chỉ với các trường hợp cụ thể rất ). Trình biên dịch có thể làm nhiều thứ để tối ưu hóa nó tốt hơn bạn và bạn sẽ hy sinh khả năng đọc cho hiệu suất mà không chắc chắn để đạt được hiệu suất tốt hơn. PS: vâng, tôi nghĩ về các hệ thống lớn với hàng ngàn người dùng đồng thời. Ngay cả ở đó, bạn không nên làm điều đó.
    2019-05-08 16: 05: 06Z
  2. Vậy, bạn sẽ sử dụng tùy chọn nào? Hoặc bạn thường sử dụng loại nào trong số chúng?
    2019-05-08 16: 06: 44Z
  3. Cái nào dễ đọc nhất. Không lưu trữ các biến tạm thời để dành một cuộc gọi đến getter. Lưu trữ biến tạm thời nếu bạn nhận được chúng từ một cuộc gọi đắt tiền đến một phương thức kinh doanh.
    2019-05-08 16: 08: 04Z
  4. @ Andy Tôi nên viết lại thành "dễ viết nhất có thể. Nếu bạn cố gắng tối ưu hóa một cái gì đó, hãy thực hiện các biện pháp trước và sau khi tối ưu hóa"
    2019-05-08 16: 14: 38Z
  5. Điều liên quan hơn hiệu năng là có sự khác biệt về ngữ nghĩa giữa hai trong môi trường đa luồng, trong đó tên có thể thay đổi trong quá trình thực thi vòng lặp.
    2019-05-08 16: 21: 19Z
1 Câu trả lời                              1                         

Tùy chọn đầu tiên sẽ chạy object.getName() 1000 lần, vòng lặp khác chỉ một lần.

Vì vậy, vâng, rõ ràng, cần có một tác động hiệu suất nhất định. Ngoài ra còn có một sự khác biệt nhỏ về ngữ nghĩa: nếu tên đó không bất biến, các luồng khác có thể thay đổi nó trong khi vòng lặp đó đang chạy. Sau đó, tùy chọn 2 might chọn thay đổi đó tại một số thời điểm ngẫu nhiên, trong khi tùy chọn 1 sẽ không làm điều đó.

Về các khía cạnh hiệu suất: trong Java, thực sự rất khó để xác định ảnh hưởng của những thay đổi mã tinh vi như vậy. Khi vòng lặp đó chạy 100 nghìn lần, trình biên dịch đúng lúc sẽ đến và dịch mọi thứ thành mã máy được tối ưu hóa cao, sử dụng các kỹ thuật như phương pháp nội tuyến, không kiểm soát vòng lặp, gấp liên tục, không chú ý. Nó thậm chí có thể phát hiện ra rằng object.getName() không có tác dụng phụ, và do đó biến mã của bạn thành thứ gì đó mà bạn đưa vào tùy chọn 2 đoạn. Tất cả điều đó xảy ra trong thời gian chạy, tùy thuộc vào thông tin lược tả mà JVM thu thập được cho JIT khi chạy mã của bạn.

Vì vậy, câu trả lời điển hình liên quan đến "hiệu suất java": tránh những sai lầm ngu ngốc (gọi một phương thức không có tác dụng phụ bên trong một vòng lặp sẽ là một lỗi như vậy), nhưng đừng mong đợi rằng ai đó có thể nói với bạn "ừ, tùy chọn 1 sẽ chạy nhanh hơn 500 ms". Tăng hiệu suất "thực" trong java được tạo bởi JIT (và tất nhiên: thiết kế thông minh để thực hiện của bạn). Do đó, rất khó để dự đoán cái này hay mã nguồn artefact sẽ có tại runtime .

Và cuối cùng: xin lưu ý rằng việc sử dụng System.out.println() khá tốn kém. Vì vậy, khi getName() của bạn thực sự chỉ tìm nạp một thuộc tính từ bộ nhớ, thì in của giá trị đó vào bảng điều khiển có thể đắt hơn nhiều lần so với tìm nạp các giá trị!

    
2
2019-05-09 05: 54: 53Z
  1. Cảm ơn bạn đã trả lời công phu. System.out.println () là một cách đơn giản để giải thích nó. Điều tôi muốn nói là tôi đã gọi rất nhiều lần cho phương thức đó (getName).
    2019-05-08 16: 40: 00Z
  2. @ Ommadawn Bạn rất hoan nghênh!
    2019-05-08 16: 44: 34Z
nguồn đặt đây