2010-11-26 33 views
13

Trình biên dịch C# hay .NET CLR có thực hiện tối ưu hóa bộ nhớ thông minh nào của chuỗi ký tự/hằng số không? Tôi có thể thề là tôi đã nghe về khái niệm "chuỗi nội bộ" sao cho trong bất kỳ hai bit mã nào trong một chương trình, chữ "đây là một chuỗi" theo nghĩa đen sẽ thực sự đề cập đến cùng một đối tượng (có lẽ là an toàn, không thay đổi?). Tôi không thể tìm thấy bất kỳ tham chiếu hữu ích nào trên Google mặc dù ...C# làm chuỗi chữ được tối ưu hóa bởi trình biên dịch?

Tôi có nghe nhầm điều này không? Đừng lo lắng - Tôi không làm bất cứ điều gì khủng khiếp trong mã của tôi với thông tin này, chỉ muốn hiểu rõ hơn về cách thức hoạt động của nó trong trang bìa.

+0

Related http://stackoverflow.com/q/372547/38206 –

Trả lời

17

EDIT: Trong khi tôi rất nghi ngờ tuyên bố dưới đây là đúng đối với tất cả các triển khai biên dịch C#, tôi m không chắc chắn nó thực sự được đảm bảo trong spec. Phần 2.4.4.5 của các cuộc đàm phán cụ thể về literals đề cập đến cùng một cá thể chuỗi, nhưng nó không đề cập đến các biểu thức chuỗi không đổi khác. Tôi nghi ngờ đây là một giám sát trong spec - Tôi sẽ gửi email cho Mads và Eric về nó.


Nó không chỉ là chuỗi ký tự. Đó là bất kỳ chuỗi nào hằng số.Vì vậy, ví dụ, hãy xem xét:

public const string X = "X"; 
public const string Y = "Y"; 
public const string XY = "XY"; 

void Foo() 
{ 
    string z = X + Y; 
} 

Trình biên dịch nhận ra rằng nối ở đây (ví z) là giữa hai chuỗi liên tục, và vì vậy kết quả cũng là một chuỗi liên tục. Do đó, giá trị ban đầu của z sẽ là cùng một tham chiếu với giá trị là XY, bởi vì chúng là hằng số thời gian biên dịch có cùng giá trị.

EDIT: Trả lời từ Mads và Eric đề xuất rằng trong các hằng số chuỗi trình biên dịch Microsoft C# và chuỗi ký tự thường được xử lý theo cùng một cách - nhưng các triển khai khác có thể khác nhau.

+0

Làm hai hằng số chuỗi giống hệt nhau trong các assembly khác nhau cũng trỏ tới cùng một đối tượng?/Liệu các chuỗi ký tự thực tập jitter? – CodesInChaos

+0

@CodeInChaos: Tôi tin rằng phụ thuộc vào thuộc tính 'CompilationRelaxationsAttribute (CompilationRelaxations.NoStringInterning)'. Tôi không muốn nói chắc chắn. –

+0

Xin chào @ JonSkeet, xin vui lòng tư vấn cho dù chuỗi nội bộ có cùng nội dung luôn có cùng tham chiếu không? Liệu nó có nghĩa là so sánh các tham chiếu của các chuỗi như vậy sẽ trở lại đúng không? –

6

This article giải thích việc thực hiện chuỗi khá tốt. Trích dẫn:

.NET có khái niệm "hồ bơi thực tập ". Về cơ bản, nó chỉ là một tập hợp các chuỗi , nhưng nó đảm bảo rằng mỗi lần thời gian bạn tham chiếu cùng một chuỗi theo nghĩa đen, bạn có thể tham chiếu đến chuỗi giống nhau . Điều này có thể là phụ thuộc vào ngôn ngữ, nhưng chắc chắn là đúng trong C# và VB.NET, và tôi sẽ rất ngạc nhiên khi thấy một ngôn ngữ mà không phải là giữ, vì IL làm cho nó rất dễ dàng để làm (có thể dễ dàng hơn là không để nội dung chính). Cũng như literals được tự động thực tập nội trú, bạn chuỗi thực tập bằng tay với các phương pháp thực tập, và có thể kiểm tra xem hoặc không có đã là một thực tập nội trú chuỗi với nhân vật cùng chuỗi trong hồ bơi sử dụng phương pháp IsInterned. Điều này phần nào trả về một cách không trực quan một chuỗi thay vì so với boolean - nếu một chuỗi bằng nhau là trong hồ bơi, tham chiếu đến chuỗi được trả về. Nếu không, null được trả về là . Tương tự như vậy, phương thức Intern trả về một tham chiếu đến một chuỗi tập trung - hoặc chuỗi bạn đã vượt qua nếu đã ở trong hồ bơi hoặc chuỗi nội bộ mới được tạo ra hoặc một chuỗi bằng đã có trong hồ bơi .

+1

Sidenote: Vì chuỗi nội bộ không được giải phóng trong thời gian trực tiếp của việc sử dụng InterDomain không đúng cách của intering có thể gây ra rò rỉ bộ nhớ. – CodesInChaos

7

Có nó tối ưu hóa chuỗi ký tự. Một ví dụ đơn giản, nơi bạn có thể thấy rằng:

string s1="A"; 
string s2="A"; 
object.ReferenceEquals(s1,s2); //true 
Các vấn đề liên quan