2010-08-17 26 views
6

Có điểm nào trong việc này không?Đấm bốc, một điều của quá khứ?

public static void Write<T>(T value) 
{ 
    textWriter.Write(value.ToString()); 
} 

... như phải này:

public static void Write(object value) 
{ 
    textWriter.Write(value.ToString()); 
} 

Thiết sang một bên khả năng vô dereference rõ ràng, Nếu tôi ở đâu để viết rất nhiều loại giá trị sử dụng phương pháp này sẽ không phải là cựu được nhiều tốt hơn bởi vì nó sẽ có phiên bản riêng của phương pháp ghi để gọi, hoặc là nó sẽ sưng lên nhị phân trong điều khoản của rất nhiều mã bổ sung được tạo ra?

Hàm ý hiệu suất của một thứ như vậy có thể không đáng kể, nhưng tôi tò mò, nó nhỏ gọn hơn nhiều so với việc cung cấp quá tải cho mỗi loại giá trị trong BCL, giống như hầu hết các nhà văn trong BCL đã làm.

Trả lời

7

Từ những gì tôi hiểu, trong cả hai trường hợp xảy ra boxing.

Cách thứ hai hiển nhiên là giá trị đã được đóng hộp.

Trước đây là ít rõ ràng hơn, nhưng như một phương pháp ảo được gọi là trên một valuetype, nó sẽ cần phải được đóng hộp để thực hiện callvirt.

Chỉnh sửa: Tôi vừa kiểm tra IL phát ra, và không có đấm bốc rõ ràng xảy ra trong trường hợp chung. Một cái gì đó rung chuông.

Chỉnh sửa 2: Tôi có thể đã nhầm lẫn với trường hợp sử dụng giao diện. Có rõ ràng boxing xảy ra.

Chỉnh sửa 3: Đấm bốc xảy ra, nếu ToString() không được ghi đè lên trong loại giá trị.

tôi có được điều này từ ECMA-335 phần 3 pg 25 (chỉ ghi nhận các trường hợp cuối cùng):

Nếu thisType là một loại giá trị và thisType không thực hiện phương pháp sau đó ptr được tham chiếu, đóng hộp và được chuyển thành con trỏ 'this' đến số callvirt của phương thức

Trường hợp cuối cùng này chỉ có thể xảy ra khiPhương phápđã được xác định trên System.Object, System.ValueType hoặc System.Enum và không bị ghi đè bởi thisType. Trong trường hợp cuối cùng này , boxing gây ra một bản sao của đối tượng ban đầu được thực hiện, tuy nhiên vì tất cả các phương pháp trên System.Object, System.ValueTypeSystem.Enum không sửa đổi tình trạng đối tượng, thực tế này có thể không được được phát hiện.

Chỉnh sửa 4:Here is a similar question on SO.

+0

Tất cả các cuộc gọi phương pháp đều thực sự ảo? Tôi nghi ngờ chỉ có giao diện situtation để làm cho boxing cần thiết, @Edit 3 bây giờ đó là hơi ngạc nhiên. Tôi sẽ nghĩ nó là một cách khác, mặc dù với các kiểu giá trị thì nó khác một chút vì bạn không thể thừa kế, vì vậy thực sự không thể là các phương thức ảo trên các kiểu giá trị và btw, đây là một câu trả lời tuyệt vời! –

1
  • cuộc gọi ảo có thể yêu cầu đấm bốc (như leppie đã nói)
  • các chung là nhỏ gọn hơn trong nguồn, nhưng không phải trong mã JIT'ed

Xét hiệu suất:

  • chung giảm kích thước nhị phân phần nào. Thời gian JIT và mã địa phương vẫn giữ nguyên, vì chỉ có các trường hợp quá tải được yêu cầu jitted là
  • nếu phương pháp này không đơn giản như trong ví dụ, giải pháp boxing sẽ liên quan đến các cuộc gọi JIT ít hơn và giảm kích thước mã (do đó cải thiện địa phương) . Đây là một hiệu ứng tích lũy khó đo ngoại trừ trong trường hợp cực đoan.

Ý chính là: không có phương pháp hoàn hảo nào cho mọi trường hợp.

+0

Trên thực tế, tôi chỉ phát hiện ra rằng boxing là không cần thiết trong mọi trường hợp (ví dụ, nơi một phương pháp ảo là overriden trong một valuetype) :) Xem sửa đổi của tôi. – leppie

+0

ahh .. thú vị. Đã thêm từ chồn;) – peterchen

1

Có, nó sẽ tránh đấm bốc trong hầu hết các trường hợp. Tôi sẽ không mong đợi rằng để làm cho bất kỳ sự khác biệt hiệu suất đáng kể trong hầu hết các trường hợp mặc dù. Như bạn nói, bản thân nó có thể không đáng kể.

Tôi cho rằng nó hiện thêm một chút gánh nặng về khả năng đọc mặc dù. Tôi nghi ngờ rằng hầu hết mọi người có tải trọng nhận thức nhiều hơn một chút khi cố gắng hiểu một phương pháp chung hơn là thực hiện một phương pháp đơn giản lấy object. Ai sẽ được sử dụng phương pháp này, và họ có đủ hạnh phúc với generics rằng nó sẽ không làm phiền họ?

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