Достался проект на поддержку, и после решения насущных проблем, пришло время рефакторинга. В одном из основных методов происходит Boxing, этот метод крутится на бекграунде для многих потоков (по экземпляру на поток, без concurrency).
имею метод для замены подстрок по шаблону.
public static (string resultStr, Dictionary<string,object> resultInsearts) InsertByTemplate(string template, Dictionary<string,object> insearts, string pattern = @"\{(.*?)(:.+?)?\}")
{
string Evaluator(Match match)
{
// В insearts по ключу находится значение для замены и возвращается.
return res;
}
var result = Regex.Replace(template, pattern, Evaluator);
}
В передаваемом словаре insearts
содержатся все варианты вставок (около 200 значений)
Возвращаемый в кортеже словарь resultInsearts
содержит только РЕАЛЬНО вставленные значения.
Наиболее используемые типы в cловаре это string, int, DateTime.
Т.е. Boxing
struct->object
происходит часто и при формировании словаря insearts
и еще при формировании resultInsearts
.
для тестов быстренько заменил словарь на
public class IndependentInserts
{
#region field
private readonly Dictionary<string, string> _strDict = new Dictionary<string, string>();
private readonly Dictionary<string, int> _intDict= new Dictionary<string, int>();
private readonly Dictionary<string, DateTime> _dateTimeDict = new Dictionary<string, DateTime>();
#endregion
#region Methode
public bool TryAddValue(string key, int value)
{
return _intDict.TryAdd(key, value);
}
public bool TryAddValue(string key, string value)
{
return _strDict.TryAdd(key, value);
}
public bool TryAddValue(string key, DateTime value)
{
return _dateTimeDict.TryAdd(key, value);
}
public bool TryGetValue(string key, out int value)
{
return _intDict.TryGetValue(key, out value);
}
public bool TryGetValue(string key, out string value)
{
return _strDict.TryGetValue(key, out value);
}
public bool TryGetValue(string key, out DateTime value)
{
return _dateTimeDict.TryGetValue(key, out value);
}
public Dictionary<string, object> Map2BoxeDictionary() //Вызывается редко по запросу пользователя
{
var boxeDictionary = new Dictionary<string, object>();
foreach (var (key, value) in _strDict)
{
boxeDictionary[key] = value;
}
foreach (var (key, value) in _intDict)
{
boxeDictionary[key] = value;
}
foreach (var (key, value) in _dateTimeDict)
{
boxeDictionary[key] = value;
}
return boxeDictionary;
}
#endregion
}
public static (string resultStr, IndependentInserts resultInsearts) InsertByTemplate(string template, IndependentInserts insearts, string pattern = @"\{(.*?)(:.+?)?\}")
{
var resultInsearts = new IndependentInserts();
string Evaluator(Match match)
{
string res = null;
var key = match.Groups[1].Value;
if (inserts.TryGetValue(key, out string strVal)) //обработка string значений
{
}
else
if (inserts.TryGetValue(key, out DateTime dateTimeVal)) //обработка DateTime значений
{
}
else
if (inserts.TryGetValue(key, out int intVal)) //обработка int значений
{
}
else
if (key.Contains("rowNumber")) //обработка служебных значений
{
}
else
{
res = match.Value;
}
return res;
}
var result = Regex.Replace(template, pattern, Evaluator);
return (result, resultInsearts);
}
С добавлением элементов все хорошо, TryAddValue
вызовет нужный метод по перегрузке.
А вот TryGetValue
нужно вызывать для каждого типа и проверять в каком же словаре находится подставляемое значение.
Хотел обсудить как бы кто поступил для замены Dictionary?
Пояснения к коду:
для вызова метода InsertByTemplate
внешний код создает словарь Dictionary<string,object> insearts
. Где ключ это строка под замену, а value
это значение замены. value
это object
- и в него помешается как ссылочный тип string, так и структуры int, DateTime
. Алгоритм метода InsertByTemplate
: это поиск в строке паттерна (через regex) и замена найденной подстроки на значение из словаря.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Всем приветЕсть регулярка, которая проверяет наименование товара и отправляет его в корзину
Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском