String и StringBuilder

Недавно отпимизировал алгоритм: раньше он работал 18 минут. Сейчас 0.4 секунды. Было необходимо сделать для сайта sitemap, дабы скормить его поисковым гиганатам. В таблице базы данных содержалось всего 18 000 строк, и алгоритм пробегал по ней за 18 минут, и делалось это вот так:

string GenerateSmap() 

{ 

string strResult = "";

SqlConnection SQLDB;

SqlCommand SQLDBCMD;

SqlDataReader SqlR;

SQLDB = new SqlConnection(strConn);

SQLDBCMD = new SqlCommand("SELECT id_article, article_num FROM articles", SQLDB);

SQLDB.Open();

SqlR = SQLDBCMD.ExecuteReader();

while (SqlR.Read())

{ 

    strResult = strResult + ("\r\n");

    strResult = strResult + ("http://www.kazved.ru/article/" + SqlR["id_article"] + ".aspx\r\n)");

    strResult = strResult + ("monthly\r\n");

    strResult = strResult + ("
0.8\r\n"); strResult = strResult + ("\r\n");

} 

SqlR.Close();

SQLDB.Close();

return strResult;

}

Представляете, 18 (!!!) минут! это целую минуту на каждую 1000 строк! Дело заключается не в SQL, а в «strResult = strResult + …». Дело в том, что, каждый раз, когда мы обращаемся к System.String, мы каждый раз создаем новый объект string в памяти. Это сильно замедляет процесс, если вы часто делаете повторяющиеся изменения в стринге. Для этих целей горздо продуктивнее использовать класс System.Text.StringBuilder, он не создает новый объект в памяти, а оперирует уже имеющимся. В данном примере, использование StringBuilder будет таким:

string GenerateSmap() { StringBuilder strResult = new StringBuilder(); 

...

        while (SqlR.Read()) 

        { 

             strResult.Append("\r\n"); strResult.Append("http://www.kazved.ru/article/" + SqlR["id_article"] + ".aspx\r\n)"); 

             strResult.Append("monthly\r\n"); strResult.Append("
0.8\r\n"); strResult.Append("\r\n");

        }

... 

return strResult.ToString(); 

}

После такого преобразования, функция стала выполняться не 18 минут, а 0.4 секунды! Мы имеем ускорение в 2700 раз!Кстати, при сооздании StringBuilder’a, вы можете задать его размер, прописав свойство Capacity, или используя оверлоад:

MyStringBuilder.Capacity = 25;
StringBuilder MyStringBuilder = new StringBuilder("Hello World!", 25);

Так же, можно прочитать и задать его длину, для этого используется свойство Length. Если вы здаете Length больше чем Capacity, то Capacity увеличится и станет равным Length. А если вы зададите Length меньше чем длина строки, что находится в StringBuilder’е, стринг билдер сам уменьшит эту строку.

Редактирование строки в StringBuilder.
Для редактирование строк в StringBuilder есть 5 методов: StringBuilder.Append, StringBuilder.AppendFormat, StringBuilder.Insert, StringBuilder.Remove, StringBuilder.Replace Названия у них говорят сами за себя, примеры использования простые. Метод StringBuilder.Append добавляет данные в конец строки, уже показывал в начале статьи, но пусть еще раз:

StringBuilder MyStringBuilder = new StringBuilder("Йа ");
MyStringBuilder.Append("креведко");
Console.WriteLine(MyStringBuilder);
StringBuilder.AppendFormat делает тоже самое что и Append, но еще применяет IFormattable, который принимает стандартные шаблоны форматирования.
int MyInt = 25;
StringBuilder MyStringBuilder = new StringBuilder("На ашем счету ");
MyStringBuilder.AppendFormat("{0:C} ", MyInt);
Console.WriteLine(MyStringBuilder);
StringBuilder.Insert делает вставку в текстовую строку в указанном месте:
StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
MyStringBuilder.Insert(6,"Beautiful ");
Console.WriteLine(MyStringBuilder);
StringBuilder.Remove удаляет в указанном месте указанное количество символов:
StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
MyStringBuilder.Remove(5,7); //с 5го по 7ой, нумерация идет от 0
Console.WriteLine(MyStringBuilder);
StringBuilder.Replace просто заменяет указанные символы на другие:
StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
MyStringBuilder.Replace('!', '?');
Console.WriteLine(MyStringBuilder);
Leave a comment

4 Comments

  1. Boglen

     /  11.12.2007

    Тру, взял на заметку.

    Ответить
  2. XAP

     /  13.12.2007

    Нашет тут моленькие подскозки для себя, спасибо.

    Ответить
  3. PetoN

     /  23.01.2008

    РЕспект за статью, я уж думал все, нужно другой язык программирования учить или еще что то в этом проде …. просто не знал принципа работы Стринг ..

    Ответить
  4. Aleksey Baryshnikov

     /  06.12.2009

    Большое спасибо, очень полезная информация

    Ответить

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>