Reflection: Đang sử dụng sự phản chiếu vẫn là Bad bad hay hay Slow chậm? Điều gì đã thay đổi với sự phản ánh từ năm 2002?


21

Tôi đã nhận thấy khi xử lý các biểu thức hoặc cây biểu thức Tôi đang sử dụng sự phản chiếu rất nhiều để đặt và nhận các giá trị trong các thuộc tính và những gì có bạn. Nó đã xảy ra với tôi rằng việc sử dụng sự phản chiếu dường như ngày càng phổ biến hơn. Những thứ như DataAnotations để xác thực, Thuộc tính ORM nặng, v.v. Tôi có tự hỏi: Điều gì đã thay đổi kể từ những năm và năm trước khi tôi thường được nói để tránh phản xạ nếu có thể?

Vì vậy, những gì, nếu bất cứ điều gì đã thay đổi? Có phải chỉ là tốc độ của máy móc? Đã có những thay đổi đối với khung để tăng tốc độ phản chiếu?

Hay không có gì thực sự thay đổi? Vẫn còn "xấu" hay "chậm" khi sử dụng sự phản chiếu?


2
Phản xạ sẽ luôn chậm hơn các cuộc gọi trực tiếp, bởi vì bạn phải thực hiện một số bước để tìm và xác minh rằng những gì bạn đang gọi tồn tại.
Michael K

Nó luôn luôn xấu .... Tất nhiên đôi khi bạn không có lựa chọn nào, tùy thuộc vào lập trình viên để biết khi nào là thời điểm đó, và tránh nó bằng cách khác.
Ramhound

Thực hiện Phản xạ với gettype để kéo một vật phẩm trong enum vẫn nhanh hơn 30 lần so với ném ngoại lệ với Enum.Pude (). Vì vậy, sự phản ánh đôi khi chiến thắng.
Brain2000

Câu trả lời:


16

Phản xạ không xấu, cũng không chậm. Nó chỉ đơn giản là một công cụ. Giống như tất cả các công cụ, nó rất có giá trị cho các kịch bản nhất định, không có giá trị cho các công cụ khác.

Nếu hiệu suất thực sự là một vấn đề, bạn luôn có thể sử dụng một thư viện như FasterFlect .

Đọc thêm
Nếu phản ánh là không hiệu quả, khi nào là thích hợp nhất?


Hoặc dynamic- rõ ràng là một thứ tự cường độ nhanh hơn sự phản chiếu.
Oded

1
Hiệu suất không phải là một vấn đề cả. Tôi chỉ nhớ một cách sinh động mọi người tránh phản xạ trở lại vào năm 2002 giống như đó là bệnh dịch. Tôi đang tự hỏi điều gì đã thay đổi kể từ đó.
thịt

3
@bledh: Không có gì. Mọi người đã quen thuộc hơn với nó bây giờ, và ít sợ nó hơn.
Robert Harvey

5
Tôi có thể "rời khỏi bãi cỏ của tôi" ở đây và nói rằng Lisp đã có điều này rất lâu trước khi OOP tồn tại ...
Michael K

Đủ công bằng. Tôi chỉ tự hỏi liệu chính sự gia tăng tốc độ của máy móc trong mười năm qua đã tạo ra sự khác biệt hay liệu có những thay đổi thực sự đối với System.Reflection đã tăng hiệu năng.
thịt

17

Lý do mọi người cảnh giác khi sử dụng sự phản chiếu một cách không cần thiết không phải là hiệu suất: vâng, có một số chi phí để sử dụng sự phản chiếu, nhưng thông thường, để giải quyết vấn đề mà không cần đến một cách tiếp cận khác với độ phức tạp tương đương, và ngay cả khi nó không, thì chi phí là hiếm khi có ý nghĩa (đặc biệt đối với phát triển cấp ứng dụng).

Sử dụng sự phản chiếu, một số giả định quan trọng mà người ta thường có thể làm cho mã nguồn bị hỏng và các công cụ như "Tìm tất cả tài liệu tham khảo" ngừng hoạt động một cách đáng tin cậy. Reflection về cơ bản cũng loại bỏ hầu hết các loại an toàn mà trình biên dịch thực thi, giả sử, C # và hầu hết các lỗi lập trình mà một hệ thống loại thường mắc phải và chuyển thành lỗi trình biên dịch, giờ trở thành lỗi thời gian chạy ở mức tốt nhất hoặc rất khó hiểu.

Vậy tại sao người ta lại dùng phản xạ? Nói một cách đơn giản, bởi vì mặc dù các vấn đề được mô tả ở trên, nó là một công cụ rất có giá trị. Với sự phản ánh, một số lợi ích của lập trình động có thể có trong một ngôn ngữ tĩnh, được gõ đúng như C # và các ngôn ngữ lập trình động đã thể hiện giá trị của chúng gần đây, đặc biệt là trong lĩnh vực lập trình web - PHP, Javascript và Python khá nổi bật , tất cả đều sử dụng kiểu gõ động và đã được chứng minh là phù hợp với lập trình web. Nhưng vì ngôn ngữ vẫn là C #, bạn có thể chọn giữ phần lớn ứng dụng của mình trong thành ngữ OOP được gõ chính xác và viết phần nhỏ trong đó hành vi động thực sự tạo ra sự khác biệt với sự phản chiếu.

Một ví dụ điển hình là khi bạn cần trưng ra các phương thức như các cuộc gọi dịch vụ web (sử dụng giao thức chưa được tích hợp vào .NET). Cách tiếp cận OOP được gõ chặt chẽ có tác dụng, nhưng nó quá hạn chế và vụng về. Nhưng nếu bạn sử dụng sự phản chiếu để ánh xạ các cuộc gọi đến các phương thức và các cặp khóa / giá trị cho các đối số, bạn có thể viết hệ thống ống nước cho một dịch vụ web như vậy một lần và sau đó sử dụng nó trên bất kỳ lớp nào bạn muốn.


13

Phản xạ vẫn chậm hơn đáng kể so với các cuộc gọi trực tiếp. Hai điều đã thay đổi:

  • Runtimes đã tối ưu hóa các cơ chế phản xạ để sự khác biệt trở nên nhỏ hơn
  • CPU đã nhanh hơn nên sự thiếu hiệu quả nhỏ dễ dàng hơn

Cùng với nhau, hai yếu tố này đã đưa chi phí phản ánh xuống đến mức bạn có thể thường xuyên sử dụng nó (khi thích hợp từ POV bảo trì) và chờ trình hồ sơ cho bạn biết liệu đó có thực sự là nút cổ chai hay không (và chắc chắn là chắc chắn rằng thời gian sẽ không được).


4
than ôi, CPU đã trở nên chậm hơn - thường là trên các thiết bị di động và máy chủ nơi mọi người đang cố gắng tiết kiệm càng nhiều hiệu quả ra khỏi máy chủ của họ càng tốt do chi phí chạy chúng.
gbjbaanb

@gbjbaanb: Tôi sẽ cung cấp cho bạn các thiết bị di động, nhưng trên máy chủ, mua nhiều phần cứng hơn là tối ưu hóa mã là lựa chọn hợp lý và được chấp nhận trong phần lớn các trường hợp, vì chi phí mua và chạy máy chủ thấp hơn rất nhiều so với các chi phí tối ưu hóa mã.
Michael Borgwardt

2
Trong một số tình huống, chi phí máy chủ lớn hơn nhiều so với chi phí phát triển. Trong phong cách quy mô lớn. Mặc dù các máy chủ là buff, hiệu năng có thể còn quan trọng hơn so với trên máy khách. Đó là một trường hợp tình huống.
Lord Tydus

1
@Lord Tydus: chắc chắn, nhưng trường hợp bạn mô tả là ngoại lệ hiếm.
Michael Borgwardt
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.