2010-02-16 25 views
41

Tôi giả định rằng các mục tiêu public hoặc privatestatic phải giảm mức sử dụng bộ nhớ, do thực tế chỉ có một bản sao của mục tiêu tĩnh trong bộ nhớ. Có vẻ như bởi vì một phương pháp là tĩnh có thể làm cho phương pháp này trở thành một điểm tiềm năng để tối ưu hóa thêm bởi trình biên dịch CLR ngoài những gì có thể với một hàm không tĩnh. Chỉ là một lý thuyết mỏng manh, vì vậy tôi đã đến hỏi tất cả các bạn.Chức năng C# tĩnh có hoạt động tốt hơn các chức năng phi tĩnh không, ngoài việc giảm mức sử dụng bộ nhớ?

Làm phương pháp staticpublic hoặc private cung cấp bất kỳ lợi ích hiệu suất tăng nào ngoài việc giảm mức sử dụng bộ nhớ?

(Lưu ý: Tôi không quan tâm đến các câu trả lời mà nói về các vấn đề tối ưu hóa sớm. Chắc chắn đó là lời khuyên âm thanh tôi theo dõi hàng ngày, nhưng điều đó không có nghĩa là tối ưu hóa là không cần thiết ở lần (double negative!). tôi để thưởng thức sự tò mò của tôi, tại ít nhất)

+3

trong C# chúng được gọi là Phương thức không hoạt động :) –

Trả lời

51

Từ Static Classes and Static Class Members (C# Programming Guide)

một cuộc gọi đến một phương pháp tĩnh tạo ra một hướng dẫn cuộc gọi trong Microsoft ngôn ngữ trung gian (MSIL), trong khi một cuộc gọi đến một phương pháp dụ tạo ra một hướng dẫn callvirt, mà cũng kiểm tra một tham chiếu đối tượng null. Tuy nhiên, hầu hết thời gian chênh lệch hiệu suất giữa hai là không đáng kể.

+13

Trên kiến ​​trúc hiện đại, chi nhánh dự đoán ăn séc rỗng với chi phí gần bằng không. –

+0

@ 280Z28 Vâng để được chính xác một số nền tảng hiện đại (PlayStation 3 thực hiện điều này nếu bộ nhớ của tôi phục vụ tôi) loại bỏ dự đoán chi nhánh gắn nhãn hiệu tốt hơn cho chi phí khó hơn để viết chương trình –

+1

@Rune FS: Trên ARM, kiểm tra được thực hiện với điều kiện hướng dẫn thực hiện. Trên SPU của Cell, bạn không có dự đoán nhánh, nhưng do một số mối quan tâm khác, nếu bạn dự định thực thi mã được quản lý trên SPU, bạn nên hoạt động chủ yếu trên các kiểu không null. Tôi thực sự đã viết một JIT khái niệm cho SPU, tập trung vào một số lượng nhỏ các kiểu dữ liệu hữu ích cho tính toán hiệu năng cao và bỏ qua các kiểm tra tham chiếu thời gian chạy null để phân tích tĩnh (thư viện Hợp đồng). –

23

Ngoài những gì người đọc nói, câu hỏi của bạn cho thấy sự hiểu lầm về phương pháp thể hiện. Bất kể chức năng có tĩnh hay không, chỉ có một bản sao của mã chức năng trong bộ nhớ. Một phương thức không tĩnh phải được gọi thông qua một đối tượng, nhưng đối tượng không mang theo bản sao riêng của phương thức đó. Vì vậy, việc sử dụng bộ nhớ của các phương pháp tĩnh và không phải là thực tế giống hệt nhau, và như những người khác đã chỉ ra, các đặc tính hiệu suất gần như giống hệt nhau.

Không tĩnh biến thành viên, tuy nhiên, không tồn tại riêng cho mọi đối tượng bạn tạo. Nhưng nó gần như luôn luôn là một sự lãng phí thời gian để lo lắng về việc sử dụng bộ nhớ, trừ khi bạn thực sự có một vấn đề liên quan đến bộ nhớ trong chương trình của bạn.

+0

"Bất kể chức năng có tĩnh hay không, chỉ có một bản sao của mã chức năng trong bộ nhớ." Cảm ơn, tôi không biết chắc chắn. –

+3

Một phương thức không tĩnh có 'this' được truyền vào như một tham số ẩn, vì vậy ai đó có thể giải thích rằng nó sử dụng nhiều không gian ngăn xếp hơn. Điều này không có vẻ đặc biệt quan trọng, mặc dù. –

+1

@Steven - nếu bạn chuyển đổi phương thức thành tĩnh, sau đó nó sẽ cần có thông số 'this' rõ ràng. –

0

MeasureIt để chắc chắn, nhưng bạn sẽ tìm thấy trừ khi bạn đang tạo cụm siêu máy tính xử lý giao dịch siêu lớn trên toàn cầu, nó sẽ không có sự khác biệt đáng kể.

1

Câu trả lời hay - về cơ bản nó không quan trọng, đó là câu trả lời cho hầu hết mọi câu hỏi thuộc loại này. Ngay cả khi nó đã tạo ra sự khác biệt - Nếu thời gian thực hiện chương trình của bạn tốn một đô la, loại vấn đề này có thể tốn một phần trăm xu, và nó là rất có thể là rằng có những thứ khác costing a great deal more.

17

Đây là một chút ít chủ đề, nhưng không kém phần quan trọng.

Sự lựa chọn làm phương pháp tĩnh hoặc dụ không nên căn cứ vào thời gian thực hiện (mà nào có vẻ như không có vấn đề). Nó phải dựa trên việc liệu phương thức có hoạt động trên một đối tượng hay không. Ví dụ, tất cả Toán.* phương pháp là tĩnh trong khi ví dụ: (hầu hết) Các phương thức String. * là instance vì chúng hoạt động trên một cá thể String. Triết lý cá nhân của tôi: một thiết kế tốt nên bù đắp cho một vài chu kỳ có thể được lưu ở nơi khác.

Một quan điểm khác về chủ đề: Gần đây tôi đã làm việc với một người đã được cho biết rằng các phương pháp tĩnh là điều ác vì chúng đưa chúng ta trở lại thời kỳ tối tăm của lập trình thủ tục và do đó sẽ tránh được bằng mọi giá. Điều này dẫn đến các ví dụ kỳ lạ về các lớp yêu cầu các cá thể truy cập vào các phương thức hoàn toàn không quan tâm đến các bên trong của đối tượng.

Phew, tôi cảm thấy thoải mái khi nhận được điều đó từ lò sưởi của mình.

+6

Quy tắc đơn giản: Nếu một phương thức hoặc thuộc tính không truy cập bất kỳ trạng thái cá thể nào ('this' và các thành viên của nó), nó có thể là tĩnh. –

+6

-1 vì tôi bị bệnh của những người có câu hỏi về tối ưu hóa/hiệu suất hợp pháp chỉ đơn giản là được nói "đừng làm điều đó". Đôi khi vi tối ưu hóa ** làm ** vấn đề. – dsimcha

+0

Thỉnh thoảng, tôi thích sử dụng các hàm tĩnh riêng nhỏ trong các lớp không tĩnh, để tôi có thể biết bằng từ khóa rằng phương thức này không trực tiếp thay đổi các biến cá thể không tĩnh. Nhưng tôi thường chỉ thêm từ khóa tĩnh khi phương thức không chạm vào một biến mẫu để bắt đầu. –

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