2014-12-24 14 views
6

Tiêu đề yêu cầu tất cả. Chúng tôi sử dụng các hành động, biểu thức với hành động và gọi lại khá rộng rãi trong mã ngày nay.Hành động có thể thay đổi không xác định, và Funcs được JIT chỉ ra?

JIT có thể tối ưu hóa các cuộc gọi này bằng cách gạch chân chúng không? Đây sẽ là một sự tăng hiệu suất rất lớn, xem xét các mẫu gọi lại, dưới dạng này hay dạng khác được sử dụng với số lượng vô lý ngày nay.

JIT không thể tối ưu hóa hành động có thể không bao giờ thay đổi. Ví dụ: tôi không thấy bất kỳ lý do gì khiến một Hành động hoặc Func, được đánh dấu bằng thuộc tính "chỉ đọc" không được tối ưu hóa.

ví dụ:

readonly Action a; 
readonly Action a1; 
readonly Action a2; 

a =() => {}; 
a1 =() => { a() }; 
a2 =() => { a1() }; 

IS a2 bao giờ được tối ưu hóa ra? Tôi không thấy lý do tại sao nó không nên.

+2

Không có số lượng suy nghĩ mơ ước sẽ nhận được nội dung lambda đó được gạch chân. –

+0

Mặc dù mã không thể được inlined, trình biên dịch C# tối ưu hóa điều này bằng cách lưu trữ bộ nhớ và tái sử dụng nó cho cả hai cuộc gọi. –

Trả lời

1

Không tối ưu hóa chính nó liên quan đến thực tế rằng nó không phải là một chức năng chính nó quan trọng, nhưng mã họ thực hiện. Bạn chỉ định một tham chiếu const cho hành động, nhưng không có bất kỳ đảm bảo nào rằng mã được thực thi bởi chúng không thể thay đổi và/hoặc có thể sản xuất hành vi không đổi. Nếu bạn không thể đảm bảo, hoặc dự đoán hành vi liên tục bằng cách nào đó, nội tuyến thường không phải là một ý tưởng hay, vì bạn có thể có luồng thực thi không thể dự đoán được, do đó hành vi, không phải là điều gì đó .net framework đang nhắm mục tiêu đến. Trong ví dụ cụ thể của bạn, nơi chúng tôi có các chức năng "giả" đơn giản, có thể tạo ra một số nội tuyến, nhưng điều này trông giống như trường hợp rất đặc biệt và rất khó xảy ra trong mã của ai đó, vì vậy hãy giới thiệu tối ưu hóa trong .net framework sẽ có lợi ích không đáng kể cho mọi người, do đó, tôi đoán, không được triển khai trong CLR.

EDIT

Như đã ghi nhận của @Sriram Sakthivel: sự hiện diện của một sự phản ánh trong .net runtime, vì vậy thể và thay đổi thời gian chạy không thể đoán trước của một hàm, có lẽ, một trong những yếu tố đáng lo ngại chính ở đây, để cho phép khuôn khổ xác định một hàm nhất định là một ứng cử viên tốt cho nội tuyến hay không.

Ngoài ra, @hvd nhận xét trong câu trả lời của @Sriram Sakthivel, lưu ý lý do tại sao từ khóa readonly chỉ đơn giản là không thể đảm bảo tính bất biến xác định.

+0

Cảm ơn bạn đã giải thích, nhưng đối số phản ánh ở trên có ý nghĩa. Hỗ trợ câu trả lời của bạn về hành động không dẫn đến hành vi không đổi. Vì vậy, tôi đoán nó có ý nghĩa là tại sao nó không phải là trong khuôn khổ ngày nay. Nhưng tôi tự hỏi liệu Hành động có nên có một siêu dữ liệu đơn giản như "bị đóng dấu" có khả năng đảm bảo tính bất biến của nó, được gạch chân không. Bởi vì, tính đến ngày nay, về mặt kỹ thuật, khả năng duy nhất tôi thấy một hành động không phải là xác định là bằng cách can thiệp qua sự phản chiếu. Tôi có thiếu bất kỳ cách nào khác không? –

+0

@ PrasannaV.Loganathar: sự phản ánh làm cho nhiều điều phức tạp hơn. Bạn có thể hỏi về C++ như 'func() const' các hàm thành viên liên tục, được * bảo đảm * để không thay đổi bất kỳ thành viên nào bên trong (nếu không có lỗi thời gian biên dịch). nhưng không có khái niệm như vậy trong .net – Tigran

+0

OK. Bạn có nhớ sửa đổi câu trả lời của mình cho câu trả lời @Sriram Sakthivel ở trên để tôi có thể đánh dấu nó không? Cả hai dường như có điểm hợp lệ và dường như tôi so sánh điều này với các cuộc gọi phương thức ảo dường như không chính xác và câu trả lời của bạn kết hợp với nhận xét ở trên dường như là câu trả lời hay nhất. –

2

Không, đại biểu không thể được tối ưu hóa cho cùng một lý do why virtual members cannot be.

  • Cuộc gọi ảo: Chúng tôi không trực tiếp qua các cuộc gọi ảo. Lý do không làm điều này là chúng tôi không biết mục tiêu cuối cùng của cuộc gọi. Chúng tôi có khả năng có thể làm tốt hơn ở đây (ví dụ: nếu 99% cuộc gọi kết thúc trong cùng một mục tiêu, bạn có thể tạo mã thực hiện kiểm tra trên bảng phương thức của đối tượng mà cuộc gọi ảo sẽ thực thi, nếu không phải là trường hợp 99%, bạn thực hiện cuộc gọi, nếu không bạn chỉ thực hiện mã nội tuyến ), nhưng không giống như ngôn ngữ J, hầu hết các cuộc gọi trong các ngôn ngữ chính chúng tôi hỗ trợ không phải là ảo, vì vậy chúng tôi không buộc phải rất tích cực về việc tối ưu hóa trường hợp này.

Đại biểu có thể trỏ đến bất kỳ điều gì trong thời gian chạy, do đó, nội tuyến không dễ dàng như vậy. Tôi biết bạn đến từ đâu với số readonly, hãy nhớ rằng chỉ đọc không phải là một viên đạn bạc. Đừng quên rằng sự phản chiếu mạnh mẽ hơn chỉ đọc, bạn có thể ghi đè lên một trường chỉ đọc với sự phản chiếu. Nếu phương thức được inlined, nó sẽ thực hiện một cái gì đó khác với những gì delegate đang trỏ.

Vì vậy, rõ ràng JIT sẽ không trực tiếp cuộc gọi đại biểu của bạn.

Cập nhật: Tôi đã tìm thấy một bài viết thú vị về chủ đề này. Can a Delegate Invocation be Inlined?

+0

Ah, đối số phản chiếu. Tôi hoàn toàn bỏ lỡ điều đó. Tính đến thời điểm này, vấn đề là chỉ đọc chỉ là một đặc tả ngôn ngữ, và CLR không có gì để làm với nó. Về mặt lý thuyết, nếu từ khóa 'niêm phong' giả định cho Hành động được cung cấp, thì sau đó nó có thể dễ dàng được gạch chân, đúng không? –

+0

PS: Tôi sẽ không so sánh điều này với các cuộc gọi ảo, kể từ khi thực hiện lớp kín. –

+1

@ PrasannaV.Loganathar 'readonly' cũng tồn tại ở cấp CIL. Tuy nhiên, việc sử dụng thời gian chạy để tối ưu hóa khá phức tạp, vì bất kỳ mã nào * có thể * có khả năng được gọi từ một hàm tạo, nơi mà các sửa đổi của các trường chỉ đọc đó vẫn được cho phép. Một từ khóa riêng biệt chỉ ra một trường có thể được thiết lập chỉ một lần, và sau đó không bao giờ sửa đổi, có nhiều vấn đề tương tự: mã * sử dụng * trường đó có thể là một hàm tạo hoặc được gọi từ hàm tạo, trước khi giá trị được đặt . – hvd

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