2012-03-04 40 views
7

Làm boxing và unboxing có hiệu suất tương tự? Hoặc unboxing nhanh hơn, giả sử?Làm boxing và unboxing có hiệu suất tương tự?

(Nếu có, bạn có thể giải thích ngắn gọn lý do chính.)

Cảm ơn

+1

Tôi không có sự thật khó khăn, nhưng tôi mong đợi unboxing sẽ nhanh hơn một chút. Khi bạn đóng một kiểu giá trị, một đối tượng mới phải được tạo và giá trị phải được sao chép vào đối tượng mới. Khi unboxing, chỉ giá trị phải được sao chép từ thể hiện được đóng hộp. Vì vậy, boxing cho biết thêm việc tạo ra một đối tượng. Điều này, tuy nhiên, thực sự nhanh chóng trong .NET, do đó, sự khác biệt có lẽ không phải là rất lớn. Cố gắng tránh toàn bộ thủ thuật đấm bốc ở nơi đầu tiên nếu bạn cần tốc độ tối đa. Hãy nhớ rằng boxing tạo ra các vật thể cần được làm sạch bởi bộ thu gom rác. –

+0

Tôi sẽ đợi một người có kiến ​​thức cụ thể hơn để viết câu trả lời thực tế, nhưng unboxing không liên quan đến cấp phát bộ nhớ, vì vậy _should_ có chi phí thấp hơn một chút, cả ngay lập tức và trong thời gian dài cho bộ thu gom rác. –

+2

(tiếp theo): Và cuối cùng (như một gợi ý chung hơn): luôn luôn làm các phép đo của riêng bạn cho trường hợp sử dụng cụ thể của bạn nếu bạn muốn sự thật cứng. Xác định các điểm nóng thực sự và không cố gắng tối ưu hóa sớm. –

Trả lời

10

Nó phụ thuộc một phần những gì bạn có ý nghĩa bởi "Đập hộp". Trong điều kiện IL, unboxing thực sự không ít hơn nó trong C#. Trong C#, "unboxing" luôn liên quan đến việc sao chép giá trị ở đâu đó, trong khi đó, nó chỉ có nghĩa là kiểm tra loại hộp và làm cho giá trị có sẵn theo cách đó.

Chúng có các đặc tính hiệu suất khác nhau mặc dù: quyền yêu cầu phân bổ đối tượng mới, nhưng không kiểm tra loại.

Mở hộp ở cấp IL thực sự chỉ cần kiểm tra xem đối tượng bạn đang cố gắng bỏ hộp có thực sự là giá trị được đóng cùng loại (hoặc giá trị tương thích) hay không. Sau đó, bạn cần phải thêm hoạt động sao chép giá trị trong phiên bản C# của unboxing.

Tôi muốn mong đợi phân bổ đắt hơn so với kiểm tra loại, đặc biệt vì không chỉ chi phí phân bổ trước mà còn thu gom rác tương ứng.

Như mọi khi, bạn nên đánh giá chi phí hoạt động của hoạt động trong ngữ cảnh mã thực tế của bạn. Tôi không mong đợi chi phí của boxing và unboxing là đáng kể trong hầu hết các ứng dụng .NET hiện đại, nơi generics cho phép bạn tránh chúng cho các bộ sưu tập, vv.

+0

Nó có thể là giá trị chỉ ra một thực tế là bất kỳ loại giá trị, cuối cùng trong các hình thức của một hoặc nhiều từ máy, phải luôn luôn được sao chép khi đọc. Lệnh IL 'isinst' phải thực hiện một bản sao của (các) giá trị đã nói, và tương tự như bất kỳ mã C# đã biên dịch nào. Tuyên bố của bạn "làm cho giá trị có sẵn [trên ngăn xếp]" tất nhiên là đúng khi mô tả ngữ nghĩa của phép toán, nhưng nó có thể dễ dàng được hiểu là mặc dù bạn "làm cho nó miễn phí", có lẽ là quan trọng cho chủ đề –

0

Theo tôi biết, unboxing rẻ hơn nhiều so với boxing. Hãy xem xét điều này:

Int32 v1 = 5; 

v1 được cấp phát trên ngăn xếp.

Object r = v1; // boxing 

Trình biên dịch có giá trị là v1 và tạo đối tượng dựa trên nó. Điều đó mất một thời gian (vì nhiều lý do).

Tuy nhiên, khi mã này được thực thi:

Int32 v2 = r; //unboxing 

những gì xảy ra là, trình biên dịch mà có được một con trỏ đến giá trị đóng hộp trong r bản thân và sau đó sao chép nó vào v2.

0

Trong điều kiện rất chung chung, có một số yếu tố cơ bản xác định hiệu suất boxing và unboxing trong môi trường thu gom rác thải.

Giả sử chúng ta đang nói về số nguyên 64 bit (ví dụ: long trong C#) trên máy x64. Chúng ta hãy tiếp tục giả định rằng điều này xảy ra bên trong một máy ảo dựa trên stack sử dụng truy tìm bộ sưu tập rác.

Trước tiên, có chi phí di chuyển bất kỳ lượng bộ nhớ nào từ vị trí này sang vị trí khác. Thời gian chạy phải sao chép giá trị thực tế của một số nguyên đóng hộp vào ngăn xếp, để chúng ta có thể làm điều gì đó hữu ích với nó. Tương tự như vậy, trong trường hợp nghịch đảo, nó phải sao chép giá trị từ ngăn xếp vào đống (nơi các kiểu tham chiếu được lưu trữ). Đây là một hoạt động khá liên quan mà chạm vào rất nhiều hệ thống con của phần cứng.Theo như chúng tôi quan tâm, yếu tố này có thể được coi là có chi phí cố định, giống nhau cho cả hai hoạt động.

Thứ hai, trong trường hợp quyền anh, một loại tham chiếu phải được cấp phát trên heap, sẽ giữ giá trị của chúng tôi. Điều này liên quan đến một số lượng hợp lý của vệ sinh, chẳng hạn như định vị bộ nhớ dự phòng, viết một tiêu đề đối tượng thích hợp vào bộ nhớ, cũng như giá trị của số nguyên của chính nó.

Thứ ba, trong trường hợp unboxing, thời gian chạy có thể phải thực hiện kiểm tra loại để xác định liệu hoạt động unboxing có thực tế hợp pháp và sẽ tạo ra kết quả chính xác hay không. Trong một số trường hợp, có thể suy luận tĩnh loại đối tượng không được đóng hộp, nhưng đây là tối ưu hóa trình biên dịch (hoặc loại tính năng hệ thống) thay vì liên quan trực tiếp đến hoạt động mà chúng tôi đang thực hiện.

Thứ tư, chi phí dài hạn ẩn của số nguyên được đóng hộp của chúng tôi là phải, giống như bất kỳ loại tham chiếu nào khác, tham gia vào việc thu thập rác. Điều này có nghĩa rằng các tham chiếu đến nó có thể phải được ghi lại, nó phải được truy tìm để xác định tính sống động và có khả năng cần sao chép vào một thế hệ khác. Mặc dù điều này tất nhiên là đúng đối với tất cả các loại tham chiếu, nhưng đây là yếu tố cần xem xét nếu chúng ta đang nghĩ về hiệu suất ở cấp độ này.

Tóm lại, chi phí phụ thuộc vào một số hành vi phiên bản cụ thể của trình biên dịch, thời gian chạy cũng như tất nhiên phần cứng mà chúng tôi đang chạy. Do đó, không dễ đưa ra câu trả lời đơn giản.