2011-01-05 3 views
1

У меня есть этот код здесь, чтобы создать строку из X пробелов.Создание строки повторяющихся символов и кеширования?

private static string GetWhiteSpaceString(int howManySpaces) 
{ 
    return new string(' ', howManySpaces); 
} 

Как можно каким-то образом кэшировать эту строку, поэтому ее создавали только, если число пробелов изменилось, например? Есть ли лучший способ, чем сохранение некоторой глобальной переменной?

Спасибо :)

+2

Если вам нужно его кешировать, это предполагает, что вы создаете s%^tloads из них. Зачем? –

+5

«Мы должны забыть о небольшой эффективности, скажем, около 97% времени: преждевременная оптимизация - это корень всего зла» - Knuth –

+0

Обратите внимание, что наличие такого метода * синхронизировано * важно, если данные являются статическими; см. мое обновление для получения дополнительной информации. –

ответ

2

Я не думаю, что вы должны кэшировать String. .Net обрабатывает его довольно хорошо.

Но если вы все еще хотите продолжить, почему бы не создать тип Dictionary<int,string> для хранения сгенерированных строк и посмотреть в него, прежде чем возвращать новый?

0

Вы можете создать статический (синхронный) Dictionary<int,string> - или, если вы кэшировать все длины до известного размера, просто string[] (быстрее и проще, нет необходимости синхронизировать либо).

Например:

static readonly Dictionary<int, string> cache 
     = new Dictionary<int, string>(); 
    public static string GetSpaces(int count) { 
     // deal with brain-dead cases first to avoid lock for short strings 
     switch (count) 
     { // note these are all interned etc 
      case 0: return ""; 
      case 1: return " "; 
      case 2: return " "; 
      case 3: return " "; 
      case 4: return " "; 
      case 5: return "  "; 
      case 6: return "  "; 
      case 7: return "  "; 
      case 8: return "  "; 
      case 9: return "   "; 
      case 10: return "   "; 
     } 
     if(count < 0) throw new ArgumentOutOfRangeException("count"); 
     lock (cache) { 
      string s; 
      if (!cache.TryGetValue(count, out s)) { 
       cache.Add(count, s = new string(' ', count)); 
      } 
      return s; 
     } 
    } 
1

Возможно, что-то подобное (только закодированы в браузере, может не работать):

Dictionary<int, string> cache = new Dictionary<int, string>(); 
private static string GetWhiteSpaceString(int howManySpaces) 
{ 
    if(cache.Keys.Contains(howManySpaces)) 
    { 
     return cache[howManySpaces]; 
    } 
    else 
    { 
     var text = new string(' ', howManySpaces); 
     cache[howManySpaces] = text; 
     return text; 
    } 
} 

Это может делать то, что вы хотите, но я бы беспокоиться об использовании памяти. Я думаю, это зависит от того, сколько howManySpaces меняется.

+0

Если вы переключите логику на использование «TryGet», вы можете избежать двойного поиска, когда элемент существует. –

1

Метод, который создает строки, вероятно, не лучшее место для их кеширования (если есть даже веская причина для их кэширования). Код, который использует строки, вероятно, содержит больше информации о том, какие строки можно использовать повторно.

Если вы кешируете строки, они будут долгоживущими объектами. Это означает, что они, вероятно, будут перемещены в кучу памяти следующего поколения. Перемещение объекта из одной кучи в другую означает, что оно будет скопировано из одного места в память в другое, так что это, по крайней мере, такая же работа, как создание новой строки.

В большинстве случаев было бы более эффективно создавать новые строки вместо их кеширования. Сборщик мусора специально предназначен для эффективного обслуживания короткоживущих объектов.

Смежные вопросы