Bạn có nên giảm thiểu việc tạo ra rất nhiều đối tượng nhỏ?


10

Khi viết một cái gì đó tạo ra nhiều (1000) đối tượng nhỏ thường xuyên, bạn có nên cố gắng giảm thiểu nó để thực hiện? Đặc biệt là nếu bạn không biết nó sẽ chạy trên hệ thống nào, từ máy tính để bàn thấp đến cao cấp hoặc thậm chí là điện thoại di động. Đối với thiết bị di động, tôi nghe nói rằng việc tạo ra nhiều đối tượng cản trở hiệu suất một chút, mặc dù tôi không biết điều đó đúng như thế nào.

Tôi có một ví dụ cho thấy ý tưởng này tốt. Trong một chương trình đồ họa, giả sử có một phương thức được sử dụng cho tất cả các bản vẽ được gọi một cách lý tưởng drawPixel(Point). Có thể có 1000 Điểm được tạo ra và nó có thể được lặp lại thường xuyên, giống như trong một trò chơi mà nó có thể được gọi hơn 60 lần một giây. Ngoài ra, drawPixel(int x, int y)có thể được sử dụng để giảm thiểu việc tạo ra nhiều đối tượng Điểm.

Trong một thiết kế hướng đối tượng, tôi nghĩ rằng việc sử dụng Point sẽ được ưu tiên hơn. Tuy nhiên, sử dụng các loại nguyên thủy có thể làm tăng hiệu suất. Hiệu suất đạt được có thể không đáng kể trong hầu hết các trường hợp, nhưng tôi không chắc về những thứ như máy di động hoặc máy cũ. Hiệu suất đạt được từ việc làm một cái gì đó như thế này và nó có phải là điều cần được xem xét?


Tôi đang gặp khó khăn trong việc tìm kiếm các tài liệu tham khảo để sao lưu điều này, nhưng nói chung trong Java 8, đừng lo lắng về điều đó. Đừng làm những điều ngu ngốc rõ ràng, nhưng nếu bạn không cố tình lãng phí thì hệ thống sẽ hoạt động tốt. Sun / Oracle đã có khoảng 20 năm để điều chỉnh quản lý bộ nhớ và quản lý bộ nhớ và họ đã thực sự giỏi về nó.

@Snowman Tôi đã nghe nói rằng các phiên bản Java mới hơn làm tốt hơn việc quản lý bộ nhớ, nhưng vấn đề tôi thấy là không có gì đảm bảo người dùng không sử dụng phiên bản cũ hơn. Đó là một phần của những gì tạo ra mối quan tâm này của tôi.
Dải băng

1
Đầu tiên làm một số đo hiệu suất. Nếu bạn có một số rắc rối thì hãy nghĩ cách tối ưu hóa. Nhưng xin đừng hy sinh khả năng duy trì mã quá sớm vì bạn nghĩ rằng bạn có thể gặp một số rắc rối về hiệu suất.
Phát hiện

2
@Stripies Hiệu suất của các đối tượng Java tồn tại ngắn đã được trả lời trong Chúng ta có nên tránh việc tạo đối tượng trong Java không? . Tuy nhiên, nếu bạn phải xử lý hàng trăm triệu đối tượng như vậy mỗi giây thì chỉ tại thời điểm đó mới xem xét lại vấn đề này.
rwong

1
Nếu bạn lo lắng về các phiên bản Java cũ hơn, hãy kiểm tra xem khi bạn cài đặt. Một JVM đủ cũ để gây ra sự cố với quản lý bộ nhớ, cũng có rất nhiều vấn đề bảo mật nổi tiếng, do đó, nhắc nhở người dùng cập nhật là giúp họ. System.getProperty("java.version")(hoặc "java.vm.version") là điểm bắt đầu.
Jerry Coffin

Câu trả lời:


17

Nói chung, không , bạn không nên tránh tạo đối tượng vì sợ mất hiệu suất. Cái này có một vài nguyên nhân.

  1. Sử dụng các đối tượng là loại điểm sử dụng Java. Tránh chúng một cách phủ nhận là một dấu hiệu cho thấy quyết định sử dụng Java có thể không phải là quyết định đúng đắn để bắt đầu.
  2. Vấn đề hiệu suất nổi tiếng là khó dự đoán. Đừng bao giờ cho rằng một cái gì đó là một nút cổ chai. Luôn luôn đo lường. Kỹ thuật hiệu suất hầu như luôn luôn là vấn đề tạo ra những thay đổi nhỏ ở chính xác đúng nơi. Bạn không thể dự đoán đúng nơi mà không cần đo nhiều hơn mức bạn có thể dự đoán về tác dụng của thuốc mà không cần thử nghiệm.
  3. Chi phí tạo đối tượng được đánh giá quá cao. Trong một JVM hiện đại, về cơ bản, nó tăng lên một con trỏ (và với các trình thu gom rác thế hệ, chi phí quản lý nó cũng không đáng kể). Có rất nhiều văn bản trên internet khuyên bạn nên tránh các đối tượng, sử dụng nhóm đối tượng, v.v ... Lời khuyên này đôi khi đúng vào những năm 1990; ngày nay nó đã lỗi thời Bạn rất khó có thể đạt được hiệu suất đủ để biện minh cho chi phí phát triển và độ phức tạp được thêm vào bằng cách tránh các Đối tượng hoặc tự quản lý chúng.

Điều đó nói rằng, có những nơi làm cho một cái gì đó thành một đối tượng không có ý nghĩa để bắt đầu. Truyền hai tọa độ cho một thói quen vẽ có thể là một trường hợp như vậy: cặp tọa độ không có sự tồn tại độc lập, nó không có danh tính, nó chỉ được sử dụng một lần và sau đó bị loại bỏ ngay lập tức, v.v.

Nếu đây là trường hợp, thì chắc chắn, hãy tiếp tục và vượt qua hai ints thay vì bọc chúng vào một đối tượng. Quan điểm của OOP không phải là mọi thứ phải là một đối tượng. Vấn đề là các đối tượng làm cho sự phát triển dễ dàng hơn ở những nơi mà chúng là giải pháp tự nhiên cho vấn đề biểu diễn dữ liệu. Đừng tránh những đồ vật có ý nghĩa - đừng giới thiệu chúng ở những nơi chúng không có.


2

Khi xem xét các tác động đến hiệu suất trước khi bạn viết mã, bạn nên cho rằng bạn không biết bạn đang làm gì.

Có một không gian rất nhỏ trên đầu cho các đối tượng trong java so với nguyên thủy. Các đối tượng của bạn càng nhỏ, tỷ lệ chi phí sẽ càng lớn. Tuy nhiên, tôi đã học được từ lâu rằng những thứ nhân đôi n không là gì so với những thứ nhân n với n.

Vì vậy, trong khi có, bạn có thể xử lý một số hệ thống có tác động đến một nửa kích thước hoặc thậm chí là thứ tư, hãy tự hỏi tại sao bạn thực sự quan tâm. Các giải pháp phức tạp cho vấn đề này sẽ không được đón nhận. Đặc biệt bởi vì lặn vào mã như vậy sẽ gây nhầm lẫn. Lập trình viên bối rối viết mã xấu. Họ viết mã n lần n nên là mã n log n. Và họ mất nhiều thời gian hơn để làm điều đó.

Bây giờ nếu bạn có thể tiết kiệm không gian cho tôi với một số mẹo phù hợp với một chiếc hộp đẹp mà tôi không phải nhìn vào bên trong hầu hết thời gian chúng ta có thể nói chuyện. Nếu đó là một hộp tôi có thể đổi ra một hộp khác khi hộp đó hoạt động tốt hơn tôi thậm chí có thể trả tiền cho nó.


2

Trong phần điều chỉnh hiệu năng tôi đã thực hiện ( ví dụ ), rất dễ để quản lý bộ nhớ là thủ phạm chính. Tôi không quan tâm đến việc họ đã điều chỉnh nhà điều hành mới và người thu gom rác điên cuồng như thế nào , tính toán nhanh nhất là không tính toán. Vì vậy, nếu tôi thấy trình quản lý bộ nhớ chiếm một phần trăm thời gian và tôi không thể tránh việc tạo các đối tượng , thì tôi sẽ tìm cách sử dụng lại chúng, thay vì liên tục tạo ra các đối tượng mới.

Tôi chỉ làm điều này nếu tôi phải làm đồ vật. Đối với đồ họa, thông thường tôi không. IMHO, đồ họa nên được vẽ , không được xây dựng . Chắc chắn, bạn có thể nói rằng một hình ảnh bao gồm các điểm, đường kết nối chúng, đa giác, văn bản, v.v. Điều đó không có nghĩa là bạn không có cách nào khác để tạo ra các vật thể từ chúng trước khi bạn vẽ chúng. Tôi chỉ vẽ chúng.

Có một phương pháp Paint. Tôi ghi đè lên đó, vẽ mọi thứ vào một bitmap, và sau đó chặn chuyển nó vào màn hình. Có vẻ tức thời. Đối với đầu vào chuột, có các phương pháp để ghi đè, để phát hiện nhấp, kéo, bất cứ điều gì.

OOP là một ý tưởng tốt cho những lý do nhất định. Những lý do đó không áp dụng trong mọi tình huống.


Tôi đồng ý, nhưng tôi cũng đồng ý với mọi người rằng thử nghiệm là cách duy nhất để biết chắc chắn. Hãy chắc chắn rằng bạn có thông số kỹ thuật thực hiện theo cách đơn giản / rõ ràng trước khi tối ưu hóa nó ... nhưng tôi đồng ý rằng mới vẫn có thể là một vấn đề.
Bill K

2

Đi trước và sử dụng phân bổ nhỏ. Các trình quản lý bộ nhớ hiện đại, đặc biệt là trình quản lý đối tượng Java được tối ưu hóa cao, cực kỳ hiệu quả. Lưu tối ưu hóa hiệu suất lớn cho một chương trình làm việc.

Rất có khả năng hiệu suất tổng thể sẽ là đủ. Nếu bạn thấy đó không phải là trường hợp, thì, và chỉ sau đó , hồ sơ hiệu suất của mã. Trong một sự nghiệp phát triển phần mềm lâu dài, tôi đã học được rằng các nút thắt cổ chai hầu như không bao giờ là nơi bạn mong đợi.

Tôi đã từng có một thành viên trong nhóm dành vài ngày để tìm kiếm thành viên đối tượng nhanh hơn 20 lần. Sự thành công! Tuy nhiên, tốc độ tổng thể tốt nhất trong sử dụng thực tế được đo bằng một phần trăm phần trăm. Thay đổi ngay lập tức được sao lưu, vì việc tăng tốc yêu cầu phân bổ bộ nhớ thành viên lớn hơn.


1

Thật đơn giản: Nếu bạn cần 1000 đối tượng nhỏ, thì bạn tạo 1000 đối tượng nhỏ và đừng lo lắng về điều đó. Nếu bạn cần 100 đối tượng nhỏ, thì việc tạo 1000 đối tượng nhỏ là ngu ngốc - tạo những đối tượng bạn cần và không nhiều hơn thế.

Nếu bạn lo lắng về hiệu suất (và nếu bạn cũng không lo lắng về hiệu suất), bạn nên có bất kỳ chức năng nào được viết một lần ở một nơi, điều này làm cho toàn bộ mã của bạn đơn giản và dễ hiểu hơn. Sau đó, nếu bạn gặp vấn đề về hiệu suất, thì việc đo lường có thể cho bạn thấy rằng có một nơi xảy ra sự cố về hiệu suất, điều này giúp mọi việc dễ dàng hơn và chỉ có một nơi bạn cần thay đổi. Hoặc đo lường cho thấy rằng một nơi này không gây ra bất kỳ vấn đề, vì vậy bạn đã hoàn thành.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.