2010-07-29 25 views
10

Tôi nhận được khoảng 5 tin nhắn mỗi giây. Mỗi trong số họ có một chuỗi, mà tôi tiếp nhau thành một chuỗi tổng thể chứa tất cả các tin nhắn đã nhậnStringBuilder hoặc + =

string _masterText = ""; 
    public void AddNewMessage(string text) // this is going to be call at least 5 times/second 
    { 
     _masterText += text;  
    } 

Đây có phải là cách appropiated để làm điều đó? hay tôi nên sử dụng thay vì StringBuilder, như:

StringBuilder _masterText = new StringBuilder(); 
    public void AddNewMessage(string text) // this is going to be call at least 5 times/second 
    { 
     _masterText.Append(text); 
    } 

Cảm ơn

+0

Tôi nghĩ câu trả lời phụ thuộc vào những gì bạn định làm với kết quả _maseterText tiếp theo. –

+0

Tôi sẽ hiển thị nó trong một memoEdit (DevExpress) trong GUI – pedroruiz

Trả lời

15

StringBuilder thường được coi là tùy chọn tốt hơn, nhưng trong trường hợp này tôi cũng không sử dụng .

Ngay cả với StringBuilder, ở tốc độ đó bộ đệm ký tự cơ bản sẽ sớm đủ lớn để bị kẹt trên Heap đối tượng lớn. Điều này sẽ gây ra vấn đề cho sức khỏe của một ứng dụng cần phải chạy trong một thời gian.

Thay vào đó, tôi muốn sử dụng System.Collections.Generic.List<string> và chỉ cần gọi phương thức đó là .Add() cho mỗi thư mới. Tùy thuộc vào những gì bạn làm với những thông điệp này bạn cũng có thể tìm thấy một loại bộ sưu tập là thích hợp hơn (có lẽ là Queue<string>), nhưng đây là hướng bạn nên đi. Bằng cách sử dụng một bộ sưu tập, bộ nhớ được sử dụng bởi mỗi chuỗi riêng lẻ sẽ không được tính vào kích thước của đối tượng bộ sưu tập. Thay vào đó, mỗi chuỗi sẽ chỉ thêm một vài byte cho tham chiếu. Điều này sẽ mất rất nhiều thời gian để chạy vào các vấn đề với nén Heap đối tượng lớn.

Nếu bạn vẫn gặp sự cố sau khi chuyển sang bộ sưu tập, bạn có thể sử dụng luồng và ghi chuỗi vào đĩa. Bằng cách này, bạn không bao giờ có nhiều hơn một chuỗi trong RAM tại một thời điểm. Bây giờ, cách duy nhất bạn có vấn đề là nếu các chuỗi riêng lẻ là 85000 byte hoặc lớn hơn.

+0

Nó cũng sẽ là một ý tưởng tốt để đổ các tin nhắn vào đĩa mỗi giờ hoặc lâu hơn để giữ mức sử dụng bộ nhớ ở mức độ lành mạnh. Tùy thuộc vào mức độ quan trọng của các thông báo này, bạn có thể muốn có một chuỗi chuyên dụng quản lý lưu trữ các tin nhắn. – ChaosPandion

+0

điều này sẽ không chạy trong cả ngày, người dùng sẽ khởi chạy ứng dụng và sẽ chạy trong 5 phút tối đa – pedroruiz

+0

@pedroruiz được rồi, được rồi. Danh sách và Hàng đợi vẫn dễ dàng hơn và nhanh hơn, và vẫn là cách chính xác để xử lý việc này. –

3

Mỗi 200ms isnt một cuộc thăm dò rất thuế, bất kể StringBuilder luôn luôn là tốt hơn.

0

StringBuilder là bạn của bạn!

8

Hãy nhớ rằng lớp String là không thay đổi. Không thể thay đổi chuỗi. Khi bạn đang "nối" chuỗi, bạn đang thực sự tạo ra một chuỗi mới, và sao chép nội dung của chuỗi gốc vào nó, sau đó thêm nội dung của chuỗi mới của bạn.

Điều này bắt đầu sử dụng bộ nhớ rất nhanh nếu bạn đang thêm chuỗi lớn.

+0

Đặc biệt một khi mỗi chuỗi trung gian chiếm 80.000 byte và đi thẳng đến LOH. –

1

Nếu bạn sẵn sàng đọc, tôi nghĩ rằng cuộc thảo luận tại http://dotnetperls.com/stringbuilder-1 thực sự hữu ích. Kiểm tra các liên kết đến các chỉ số thực về tốc độ và mức sử dụng bộ nhớ.

Ngoài ra, hãy xem cuộc thảo luận của Joel Spolsky về "Shlemeil the Painter's Algorithm". Mặc dù anh ta nói về hàm strcat của C, nguyên tắc áp dụng cho toán tử cộng của C# trên chuỗi. Bên cạnh đó, nó là tốt cho một tiếng cười.

Nói chung, tôi khuyên bạn nên sử dụng StringBuilder nếu bạn thực hiện thao tác chắp thêm nhanh chóng hoặc với nhiều chuỗi lớn.

0

Nó cũng phụ thuộc vào kịch bản. Không có nghi ngờ nó là nhanh hơn để thêm vào danh sách chung chung như so sánh với đối tượng stringbuilder. Nhưng trong thời gian truy xuất dữ liệu từ danh sách chung, nó sẽ chậm hơn nhiều so với đối tượng stringbuilder.

Trình tạo chuỗi sẽ trả về nhanh chóng bằng _masterText.ToString() nhưng với danh sách chung, bạn có thể phải kéo giá trị bằng cách sử dụng lặp lại. Và đó sẽ là quá trình tốn kém như: -

for (int x = 0; x < 100; x++) 
    { 
     Label3.Text += gen_list[x]; 
    } 

Hoặc bạn có thể thử với

Label3.Text = string.Join ("", gen_list.ToArray());

thì hoạt động truy xuất sẽ chậm hơn và tốn kém, và bạn có thể nhận thấy sự tăng đột biến của CPU một cách dễ dàng.