Việc thực hiện RuntimePropertyInfo
(đó là lớp con cụ thể của PropertyInfo
với nhiều loại runtime) thực hiện GetValue
và SetValue
bằng cách gọi các phương thức getter và setter thông qua phản ánh (MethodInfo.Invoke
), trong khi đại biểu tạo của bạn có thể gọi là phương pháp trực tiếp. Do đó, câu hỏi sẽ tóm tắt: tại sao RuntimeMethodInfo.Invoke
quá chậm khi so sánh với lời gọi được biên dịch?
Khi bạn dịch ngược (hoặc nhìn vào các nguồn tài liệu tham khảo cho) RuntimeMethodInfo.Invoke
, bạn có thể thấy rằng đây có lẽ là bởi vì Invoke
thực hiện rất nhiều nhiệm vụ:
- nó thực hiện kiểm tra tính nhất quán (làm số lượng và loại các thông số được thông qua khớp với chữ ký không? Ví dụ được thông qua khớp với kiểu khai báo? là một cá thể được truyền mặc dù phương thức là tĩnh?),
- nó thực hiện khả năng hiển thị và (nếu kiểm tra khả năng hiển thị bị phá vỡ) kiểm tra bảo mật,
- nó unwraps mảng tham số, xử lý ref pa các ống thông theo cách đặc biệt để chúng có thể được ghi lại sau,
- nó sẽ mở các tham số nếu cần,
- cần tìm con trỏ phương thức dựa trên xử lý kiểu thời gian và xử lý phương pháp liên quan đến RuntimeMethodHandle và sau đó gọi phương pháp,
- nó sẽ trả về giá trị trả lại nếu cần và
- hộp và đặt vào mảng tham số bất kỳ thông số ref/out nào.
Thời gian chạy sẽ thực hiện kiểm tra tính nhất quán, bảo mật và khả năng hiển thị tương tự khi biên dịch đại biểu của bạn thành mã gốc có thể thực thi. Nó cũng phát ra mã cho boxing/unboxing, vv Tuy nhiên, nó chỉ cần làm những điều này một lần, và sau đó có thể đảm bảo rằng mã này là an toàn để thực thi. Điều này làm cho phương thức thực tế gọi một hoạt động rất rẻ (tải các tham số và chuyển đến địa chỉ phương thức).
Ngược lại, mỗi cuộc gọi đến RuntimeMethodInfo.Invoke
(và do đó để GetValue
/SetValue
) cần phải lặp lại tất cả công việc, vì bối cảnh - thông số, ví dụ, và sử dụng các kiểu trả về - không được biết đến. Và đây có lẽ là lý do tại sao nó quá chậm.
Về những gì bạn có thể bị thiếu: nếu bạn phát ra các đại biểu yêu cầu tài sản của riêng bạn, tất nhiên bạn cần phải giải quyết các thông số về boxing/unboxing, ref/out, v.v.
Nguồn
2012-10-12 13:33:38
FYI, nếu bạn đang tìm kiếm một cách dễ dàng hơn để nhận được một tăng hiệu suất hơn Reflection.Emit, bạn có thể chỉ Delegate.CreateDelegate với PropertyInfo.GetGetMethod/PropertyInfo.GetSetMethod (và bộ nhớ cache đại biểu đương nhiên). – Ani
Tôi phải khóa đối tượng của đối tượng trong ủy nhiệm. Các phương thức 'GetValue' và' SetValue' lấy cá thể đối tượng, tại thời điểm cuộc gọi. –
Delegate.CreateDelegate có thể tạo cả các đối tượng ủy nhiệm mở và đóng. – Ani