лучший способ очистить содержимое of.NET ' S StringBuilder



Я хотел бы спросить, что вы думаете, это лучший способ (длится меньше / потребляет меньше ресурсов), чтобы очистить содержимое для повторного использования StringBuilder. Представьте себе следующий сценарий:



StringBuilder sb = new StringBuilder();
foreach(var whatever in whateverlist)
{
sb.Append("{0}", whatever);
}

//Perform some stuff with sb

//Clear stringbuilder here

//Populate stringbuilder again to perform more actions
foreach(var whatever2 in whateverlist2)
{
sb.Append("{0}", whatever2);
}


и при очистке StringBuilder я могу думать о двух возможностях:



sb = new StringBuilder();


или



sb.Length = 0;


что является лучшим способом, чтобы очистить его и почему?



спасибо.



EDIT: я мент с текущей версией .NET 3.5.

617   10  

10 ответов:

Если вы делаете это в .NET 2.0 или 3.5, напишите метод расширения, чтобы сделать это следующим образом:

/// <summary>
///     Clears the contents of the string builder.
/// </summary>
/// <param name="value">
///     The <see cref="StringBuilder"/> to clear.
/// </param>
public static void Clear(this StringBuilder value)
{
    value.Length = 0;
    value.Capacity = 0;
}

затем вы можете очистить его, как это:

someStringBuilder.Clear();

затем, когда 4.0 выходит, вы можете отказаться от своего метода расширения в пользу версии 4.0.

обновление: это, вероятно, не очень хорошая идея, чтобы установить емкость до нуля. Это гарантирует перераспределение при добавлении в конструктор, если вы повторно используете один и тот же экземпляр. Тем не менее, память в экземпляр компоновщика не освобождается, пока не будет установлено очень малое значение емкости (например, 1). Значение по умолчанию свойства Capacity равно 16. Возможно, вы захотите использовать 16 или (хотя это менее эффективно) установить емкость дважды:

  • установите его в 1 или ноль, чтобы очистить память
  • установите его в исходное значение емкости (которое может отличаться от 16), чтобы восстановить его.

в .NET 4.0 вы можете позвонить sb.Clear() но в старых версиях вы должны установить sb.Length = 0.

The Clear() метод был добавлен в .NET 4.0.

создать новый StringBuilder. Старый поддерживает ресурсы, связанные с ним (например, буфер максимальной длины), которые лучше всего просто собирать мусор.

из содержимого сообщества на MSDN:

эффективно очистить ваш stringbuilder без его уничтожения использование:

 someStringBuilder.length = 0;
 someStringBuilder.capacity = 0;

это уничтожает как его содержимое, так и изменяет его размер до нуля. Как отмечалось выше очистить размер может повлиять меньше приложения.

Я думаю, что вы занимаетесь преждевременной оптимизацией.

держу пари, что делаю sb.Length=0; было бы самым быстрым, чтобы не создавать другой объект и не помещать другой объект в сторону для GC, чтобы в конечном итоге собрать.

Я думаю, что создание нового StringBuilder будет лучшим выстрелом для проблем с памятью. и установка sb.Length было бы лучшим выстрелом для проблем скорости..

в .NET Framework 4 новых метода были введены в StringBuilder класса. Имя метода - "Clear". Этот метод позволяет очистить или удалить значения или данные из StringBuilder объекты.

вот пример для этого.

    System.Text.StringBuilder objSB = new System.Text.StringBuilder();
    //Append values
    objSB.Append("This is .Net Blog.");
    objSB.Append("You can get latest C# Tips over here.");

    //Display on screen
    Response.Write(objSB.ToString());
    Response.Write("<br/><br/>");

    //Clear object using Clear method
    objSB.Clear();

    //Append another values
    objSB.Append("This blog is very useful for .Net Beginners");

    Response.Write("After Clear<br/><br/>");
    //Display on screen
    Response.Write(objSB.ToString());

Если вы хотите уменьшить использование памяти, я бы использовал профилировщик CLR, чтобы проверить, сколько памяти ваши объекты StringBuilder используют в своем жизненном цикле, используя методы, описанные выше. Затем вы можете убедиться, что выбранный вами вариант подходит для ваших нужд и высвобождает необходимые вам ресурсы.

Я бы сказал, что лучший способ сделать это, чтобы использовать sb = new StringBuilder();. При этом я думаю, что было бы еще лучше, если бы вы сделали новый объект строителя строк вообще.

EDIT

Я надеюсь, что это само собой разумеется, что это лучшее решение.

public StringBuilder MakeString(IEnumerable<CoolType> list)
{
    StringBuilder sb = new StringBuilder();

    foreach(var whatever in list)
    {
        sb.Append("{0}", whatever);
    }
}

var sb = MakeString(whateverList);
// Do stuff
// Clear stuff
sb = MakeString(whateverList2);

просто вызовите метод Clear () просто установите length = 0 , Мы также можем установить Capacity = 0, если хотим сохранить память

public StringBuilder Clear() {
        this.Length = 0;
        return this;
 }

Ref: In referencesource.microsoft.com

// P.S. to be ultra efficient 
// make a good guess at the initial allocation too !!!!
int PerWhatever_SizeEstimate = 4; // a guess of average length... you known your data
StringBuilder sb = new StringBuilder( whateverlist.Length * PerWhatever_SizeEstimate);

// reallocation needed? 
// if you want to be efficient speed and memory wise... 
sb.Length = 0;  // rest internal index but don't release/resize memory
// if a ...BIG... difference in size
if( whatever2.Length < whatever.Length * 2/3  
 || whatever2.Length > whatever.Length * 1.5)
{
    //scale capacity appropriately
    sb.Capaciy = sb.Capacity * whatever2.Length / whatever.Length;
}

Comments

    Ничего не найдено.