2012-01-01 30 views
5

Tôi không hiểu:Sự hiểu lầm về chuỗi ký tự?

MSDN nói

http://msdn.microsoft.com/en-us/library/system.string.intern.aspx

Do đó, một thể hiện của một chuỗi chữ với một giá trị cụ thể chỉ tồn tại một lần trong hệ thống. Ví dụ, nếu bạn gán cùng một chuỗi ký tự cho một số biến số , thời gian chạy sẽ truy xuất cùng một tham chiếu đến chuỗi theo nghĩa đen từ hồ bơi thực tập và gán nó cho mỗi biến.

Hành vi này có phải là Mặc định (không có thực tập sinh) không? hoặc bằng cách sử dụng phương pháp Intern?

  • Nếu mặc định, tại sao tôi muốn sử dụng thực tập? (ví dụ sẽ một lần đã ...)?

  • Nếu nó không mặc định: nếu tôi viết 1000 lần hàng này:

    Console.WriteLine ("lalala");

1) tôi sẽ nhận được 1000 lần xuất hiện "lalala" trong bộ nhớ? (không sử dụng thực tập ...)

2) sẽ "lalala" cuối cùng sẽ được Gc'ed?

3) Có "lalala" đã được lưu trữ không? và nếu có, tại sao tôi cần phải "lấy" nó từ hồ bơi, và không chỉ viết "lalala" một lần nữa?

Im một chút nhầm lẫn.

Trả lời

9

Chuỗi ký tự được lấy tự động (vì vậy, nếu mã của bạn chứa "lalala" 1000 lần, chỉ một trường hợp sẽ tồn tại).

Các chuỗi như vậy sẽ không nhận được GC và bất kỳ khi nào chúng được tham chiếu, tham chiếu sẽ là chuỗi được thực hiện.


string.Intern là có cho các chuỗi có không literals - nói từ người dùng nhập vào hoặc đọc từ một tập tin hoặc cơ sở dữ liệu và bạn biết sẽ được lặp lại rất thường xuyên và như vậy có giá trị thực tập cho các đời của quá trình.

+0

vậy tại sao tôi lại muốn sử dụng 'string.intern (" lalala ")' nếu nó tự động lấy từ hồ bơi? Tôi chỉ có thể sử dụng "lalala" .... xin vui lòng làm rõ ... :) toda. –

+0

@RoyiNamir - Đã thêm một số thông tin về 'string.Intern'. Hy vọng rằng làm rõ một chút. – Oded

+0

luôn cảm ơn bạn. - phần thứ hai làm rõ mọi thứ cho tôi. –

5

Thực tập là điều gì đó xảy ra sau hậu trường, vì vậy bạn là một lập trình viên không bao giờ phải lo lắng về điều đó. Bạn thường không phải đặt bất cứ thứ gì vào hồ bơi, hoặc lấy bất cứ thứ gì từ hồ bơi. Giống như bộ sưu tập rác thải: bạn không bao giờ phải gọi nó, hoặc lo lắng rằng nó có thể xảy ra, hoặc lo lắng rằng nó có thể không xảy ra. (Vâng, trong 99.999% các trường hợp. Và 0,001 phần trăm còn lại là khi bạn đang làm những thứ rất kỳ lạ.)

Trình biên dịch sẽ chăm sóc thực tập tất cả các chuỗi ký tự được chứa trong tệp nguồn của bạn, vì vậy "lalala" sẽ được thực tập mà không cần phải làm gì, hoặc có bất kỳ sự kiểm soát nào về vấn đề này. Và bất cứ khi nào bạn đề cập đến "lalala" trong chương trình của bạn, trình biên dịch đảm bảo tìm nạp nó từ nhóm thực tập, một lần nữa mà không cần phải làm gì, cũng như không có bất kỳ sự kiểm soát nào về vấn đề này.

Hồ bơi thực tập chứa số lượng chuỗi cố định nhiều hơn hoặc ít hơn, thường có kích thước rất nhỏ, (chỉ bằng một phần nhỏ tổng kích thước của .exe), vì vậy không quan trọng là chúng không bao giờ bị rác - được thu thập.


EDIT

Mục đích của chuỗi thực tập là để cải thiện đáng kể thời gian thực hiện các hoạt động chuỗi nhất định như Equals(). Phương pháp Equals() của String trước tiên kiểm tra xem các chuỗi có bằng tham chiếu hay không, cực kỳ nhanh; nếu các tham chiếu bằng nhau, thì nó trả về true ngay lập tức; nếu các tham chiếu không bằng nhau, và các chuỗi đều được tập trung, thì nó trả về false ngay lập tức, bởi vì chúng không thể bằng nhau, vì tất cả các chuỗi trong nhóm thực tập đều khác nhau. Nếu không có trường hợp nào ở trên giữ đúng, thì nó tiếp tục với một ký tự bằng so sánh chuỗi ký tự. (Trên thực tế, nó thậm chí còn phức tạp hơn thế, bởi vì nó cũng kiểm tra mã băm của các chuỗi, nhưng hãy giữ mọi thứ đơn giản trong cuộc thảo luận này.)

Vì vậy, giả sử bạn đang đọc mã từ một tệp trong chuỗi s, và bạn có một câu lệnh switch có dạng sau:

switch(s) 
{ 
    case "cat": .... 
    case "dog": .... 
    case "tod": .... 
} 

các xâu "mèo", "con chó", "tod" đều được thực tập nội trú, nhưng bạn đang so sánh mỗi người trong số họ chống lại s, đã không được tập trung, vì vậy bạn không gặt hái những lợi ích của hồ bơi thực tập. Nếu bạn thực tập s ngay trước câu lệnh switch, thì các phép so sánh sẽ được thực hiện bởi câu lệnh switch sẽ nhanh hơn rất nhiều. Tất nhiên, nếu có bất kỳ khả năng nào tệp của bạn có thể chứa rác, thì bạn KHÔNG muốn làm điều này, vì việc tải nhiều chuỗi ngẫu nhiên vào hồ bơi thực sự chắc chắn sẽ giết hiệu suất chương trình của bạn, và cuối cùng hết bộ nhớ.

+0

'trình biên dịch chắc chắn để lấy nó từ các hồ bơi intern' ... vì vậy khi WIll tôi muốn sử dụng một cách rõ ràng string.intern ?? –

+0

@Oded đã trả lời câu hỏi này. Tôi cũng sẽ cố gắng đưa ra một ví dụ trong câu trả lời của tôi. –

+0

Tôi đã thêm một ví dụ. –

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