2012-02-17 38 views
10

Trong C#, có bất kỳ sự giảm đáng kể nào về cấp phát bộ nhớ khi truyền tham chiếu DateTime như một tham số cho một hàm trái ngược với việc truyền nó theo giá trị không?Tôi có thể giảm phân bổ bộ nhớ bằng cách chuyển tham số DateTime bằng tham chiếu trong C#?

int GetDayNumber(ref DateTime date) 

vs

int GetDayNumber(DateTime date) 

Mã bên trong hàm không được sửa đổi ngày trong mọi trường hợp.

+1

Bất kỳ lý do nào bạn sẽ không sử dụng 'date.Day'? –

+0

Mức độ quan trọng đáng kể? Một đối tượng DateTime không chính xác là một bộ nhớ hogger. Nó có khả năng xảy ra trên stack hoặc trong một thanh ghi anyway, và thậm chí khi bạn vượt qua một tham chiếu của bạn vẫn đi qua dữ liệu (tức là tham khảo) có thể có cùng kích thước (nó không thể nhỏ hơn nhiều vì DateTime là nhỏ). –

+0

Chức năng này thực hiện điều gì đó khác với ngày.Thêm Chức năng này được gọi là hàng triệu lần vì vậy, bất kỳ cải thiện nào trong đó, sẽ là tuyệt vời.Tôi đoán sau đó, sự khác biệt trong cấp phát bộ nhớ trong ngăn xếp là "Kích thước ngày giờ" - "Kích thước tham chiếu" – jeroko

Trả lời

12

A DateTime là cấu trúc 8 byte. A ref có 4 hoặc 8 byte tùy thuộc vào kiến ​​trúc đích của bạn. Vì vậy, tốt nhất là bạn nên tiết kiệm 4 byte bộ nhớ ngăn xếp, điều này hoàn toàn không liên quan.

Thậm chí có khả năng là ref ngăn một số tối ưu hóa, chẳng hạn như đặt DateTime trong sổ đăng ký, do đó thực sự tăng mức sử dụng bộ nhớ.

Đây là trường hợp rõ ràng về tối ưu hóa sớm. Đừng làm thế.

+0

Điều gì sẽ xảy ra nếu phương pháp này được gọi là Triệu lần liên tiếp? điều này phụ thuộc vào khi nào tham chiếu được giải phóng cho GC. Nếu nó ngắn ngủi, ok, nhưng nếu nó được giữ trong một thời gian không đáng kể, liệu ref có hiệu quả tích cực không? –

+1

1) Một triệu lần liên tiếp sẽ không có tác dụng gì cả. Bạn sẽ nhận được 8 byte một triệu lần. Một triệu lần đệ quy sẽ là một vấn đề, nhưng bạn hiếm khi có chức năng đệ quy sâu trong C#. 2) GC không đi vào điều này. Một 'DateTime' cục bộ được cấp phát trên ngăn xếp không cần GC được giải phóng. Khi hàm thoát, con trỏ ngăn xếp sẽ được điều chỉnh và tất cả các biến cục bộ thực sự sẽ biến mất. Điều này là thực tế miễn phí. | Nó chỉ trở nên phức tạp nếu các biến cục bộ của bạn không thực sự cục bộ (chụp lamda, async-await, iteratiors yield, ...), nhưng đó không phải là trường hợp ở đây. – CodesInChaos

1

Tôi không nghĩ có bất kỳ sự giảm thiểu đáng kể nào về mức sử dụng bộ nhớ, nhưng tôi tin rằng có một số.

Khi đi qua các datetime với ref đó sẽ không thể được tạo ra một đối tượng datetime mới như khi bạn không sử dụng từ khóa ref

-2

Bên trong, giá trị DateTime được biểu diễn dưới dạng số tick, đó là một chặng đường dài 64 bit.

Bộ xử lý 64 bit sẽ cần cùng một lượng bit để gửi địa chỉ của biến.

Nhưng nếu làm việc trong bộ xử lý 32 bit, phạm vi địa chỉ của bạn nhỏ hơn kích thước của ngày giờ. Vì vậy, hiệu suất có thể được cải thiện.

Tuy nhiên, trên thực tế, sự khác biệt gần như không bao giờ được chú ý.

+0

Lỗi này được thông qua ** theo giá trị **. Ngay cả khi nó sẽ là một kiểu tham chiếu, mà nó không phải là, nó vẫn sẽ được truyền theo giá trị. – oleksii

+1

DateTime là một cấu trúc, vì vậy không được chuyển qua tham chiếu - trừ khi có ai đó thay đổi C# mà không nói cho tôi biết? –

+2

Bạn không chính xác, DateTime là một cấu trúc và do đó được truyền theo giá trị. –

2

Giống như với bất kỳ câu hỏi tương tự nào khác, bạn cần tự mình đặt thời gian. Một vài bộ xử lý có đóng vai trò quan trọng không? Sẽ có thêm một vài byte đóng vai trò quan trọng trong việc tiêu thụ bộ nhớ trong ứng dụng của bạn?

Để tối ưu hóa vi mô và tập trung vào giải quyết vấn đề thực sự đầu tiên.

0

Bạn có thể, tuy nhiên vì DateTime là một cấu trúc và chỉ được phân bổ trên ngăn xếp, có rất ít chi phí vì không có phân bổ heap như có cho một lớp. Cũng vì giá trị được chuyển thành một thể hiện mới, không gian trên ngăn xếp sẽ được giải phóng ngay khi bạn rời khỏi phương thức.

var date = DateTime.Today; // One date time object is allocated and assigned to the stack. 
DoSomething(date); // this will result in a second date time object being allocated and assigned to the stack. 

private void DoSomething(DateTime date) 
{ 
    // do something with the date time object. 
} // As soon as we leave this method, the date time object is removed from the stack as it is now out of scope. 
+2

Nó không phải là GC giải phóng cấu trúc trên ngăn xếp. Chúng chỉ đơn giản là "giải phóng" bằng cách điều chỉnh con trỏ ngăn xếp ở phần cuối của một hàm, vì vậy chúng bây giờ nằm ​​trong phần không được sử dụng của ngăn xếp. – CodesInChaos

+0

Điểm tốt, tôi sẽ cập nhật câu trả lời của mình để phản ánh. –

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