2013-04-19 19 views
5

Tôi có một chức năng đang đi qua chuỗi tìm mẫu và thay đổi các phần của nó. Tôi có thể tối ưu hóa nó bằng cách chènlà String.Contains() nhanh hơn là đi qua toàn bộ mảng char trong chuỗi?

if (!text.Contains(pattern)) return; 

Nhưng, tôi đang thực sự đi qua toàn bộ chuỗi và so sánh các bộ phận của nó với mô hình, vì vậy câu hỏi là, làm thế nào String.Contains() thực sự hoạt động? Tôi biết có một câu hỏi như vậy - How does String.Contains work? nhưng câu trả lời là không rõ ràng. Vì vậy, nếu String.Contains() cũng đi qua toàn bộ chuỗi ký tự và so sánh chúng với mẫu mà tôi đang tìm kiếm, nó sẽ không thực sự làm cho chức năng của tôi nhanh hơn, nhưng chậm hơn.

Vì vậy, bạn nên thử một tối ưu hóa như vậy? Và - có thể cho String.Contains() thậm chí còn nhanh hơn chức năng mà chỉ cần đi qua toàn bộ mảng và so sánh từng ký tự đơn với một số không đổi?

Đây là mã:

public static char colorchar = (char)3; 

    public static Client.RichTBox.ContentText color(string text, Client.RichTBox SBAB) 
    { 
     if (text.Contains(colorchar.ToString())) 
     { 
      int color = 0; 
      bool closed = false; 
      int position = 0; 
      while (text.Length > position) 
      { 
       if (text[position] == colorchar) 
       { 
        if (closed) 
        { 
         text = text.Substring(position, text.Length - position); 
         Client.RichTBox.ContentText Link = new Client.RichTBox.ContentText(ProtocolIrc.decode_text(text), SBAB, Configuration.CurrentSkin.mrcl[color]); 
         return Link; 
        } 

        if (!closed) 
        { 
         if (!int.TryParse(text[position + 1].ToString() + text[position + 2].ToString(), out color)) 
         { 
          if (!int.TryParse(text[position + 1].ToString(), out color)) 
          { 
           color = 0; 
          } 
         } 
         if (color > 9) 
         { 
          text = text.Remove(position, 3); 
         } 
         else 
         { 
          text = text.Remove(position, 2); 
         } 
         closed = true; 
         if (color < 16) 
         { 
          text = text.Substring(position); 
          break; 
         } 
        } 
       } 
       position++; 
      } 
     } 
     return null; 
    } 
+0

Bạn sẽ phải đăng (phác thảo) phần còn lại của mã. Nhưng có, rất có thể bạn đang làm công việc gấp đôi ở đây. –

+4

Tại sao bạn không thời gian cả hai phương pháp tiếp cận trong một vòng lặp for? – Habib

+0

@Habib đó không phải là một ý tưởng tồi :) – Petr

Trả lời

3

Nếu string.Contains là không đủ nhanh, sau đó thì chắc chắn rằng bất kỳ tối ưu hóa của một phương pháp tương đương sẽ đủ nhanh.

Thứ nhất, bạn có chắc chắn rằng chuỗi.Contains thực sự không đủ nhanh? Tôi cảm thấy khó tin trừ khi bạn đang thực hiện một số xử lý chuỗi lớn.

Thứ hai, nếu bạn chắc chắn điều này, thì bạn cần phải xem xét một số cách khác để đạt được mục tiêu của bạn, có thể sử dụng một số loại tiện ích đánh chỉ số như Lucene.Net

+0

eh, tôi nghĩ có gì đó sai với câu hỏi của tôi, bởi vì đây không phải là những gì tôi đã yêu cầu .. Tôi không có nghĩa là String.Contains() là không đủ nhanh - Tôi muốn biết nếu thêm nó vào đầu chức năng của tôi có thể làm cho nó nhanh hơn hay không (toàn bộ chức năng) bởi vì tôi tin rằng tôi đang làm điều tương tự String.Contains(), do đó, nó sẽ làm tương tự hai lần – Petr

+0

@Petr Cách tốt nhất để tìm hiểu xem mã của bạn có nhanh hơn hay không là thực hiện thay đổi, sau đó lược tả nó :) – Patashu

+0

Chà, điều này thật ngây thơ. Một thuật toán tìm kiếm chuỗi Boyer-Moore đơn giản sẽ hoạt động tốt hơn 'string.Contains'. – leppie

0

Yes.

Và không có lỗi (ahhm ...).

Có nhiều cách tốt hơn để tìm kiếm nhiều bản chất trong các văn bản rất dài, nhưng đối với các tập quán phổ biến nhất String.Contains (hoặc IndexOf) là tốt nhất.

Cũng IIRC nguồn gốc của String.Contains có sẵn trong nguồn Net chia sẻ

Oh, và nếu bạn muốn có một so sánh hiệu suất mà bạn chỉ có thể đo lường cho use-case chính xác của bạn

0

Kiểm tra này tương tự gửi How does string.contains work

tôi nghĩ rằng bạn sẽ không thể chỉ đơn giản là làm bất cứ điều gì nhanh hơn String.Contains, trừ khi bạn muốn sử dụng tiêu chuẩn chức năng CRT wcsstr, có sẵn trong msvcrt.dll, mà không phải là dễ dàng như vậy

1

Câu trả lời ngắn gọn là tối ưu hóa của bạn không có tối ưu hóa nào cả.
Về cơ bản, String.Contains(...) chỉ trả String.IndexOf(..) >= 0
Bạn có thể cải thiện alogrithm của bạn để:

int position = text.IndexOf(colorchar.ToString()...); 
if (-1 < position) 
{ /* Do it */ } 
0

Trừ khi bạn đã cấu hình ứng dụng của bạn và xác định rằng phù hợp với String.Contains là một cổ chai, bạn nên không làm bất cứ tối ưu hóa sớm như vậy. Đó là cách quan trọng hơn để giữ cho ý định của mã của bạn rõ ràng.

Trả lời trong khi có nhiều cách để triển khai các phương pháp trong.Các lớp cơ sở NET, bạn nên giả định các triển khai mặc định là đủ tối ưu cho các trường hợp sử dụng của hầu hết mọi người. Ví dụ: việc triển khai .NET có thể sử dụng hướng dẫn cụ thể về x86 để so sánh chuỗi. Điều đó sẽ luôn luôn nhanh hơn những gì bạn có thể làm trong C#.

Nếu bạn thực sự muốn chắc chắn liệu mã so sánh chuỗi tùy chỉnh của mình có nhanh hơn String.Contains hay không, bạn cần phải đo lường cả hai bằng cách sử dụng nhiều lần lặp, mỗi chuỗi có một chuỗi khác nhau. Ví dụ: sử dụng Stopwatch class để đo thời gian.

0

Nếu bây giờ chi tiết bạn có thể sử dụng để tối ưu hóa (không chỉ đơn giản là kiểm tra) chắc chắn bạn có thể làm cho phương thức của bạn nhanh hơn so với chuỗi.Contains, nếu không - không.

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