只要字符串不死,每次操作都會導致GC加載,即使是StringBuilder插入/刪除調用。 我會通過插入點剪切源字符串,然後用需要插入的數據「壓縮」它。 之後,您可以將列表中的字符串串起來,以獲得結果字符串。
下面是一個示例代碼,做拆分/壓縮操作。 它假定字段被定義爲(位置,長度,值)的簡化。
public class Field
{
public int pos { get; set; }
public int len { get; set; }
public string value { get; set; }
public string tag { get; set; }
}
class Program
{
static void Main(string[] args)
{
var source = "You'r order price [price] and qty [qty].";
var fields = new List<Field>();
fields.Add(new Field()
{
pos = 18,
len = 7,
value = "15.99$",
tag = "price"
});
fields.Add(new Field()
{
pos = 37-3,
len = 5,
value = "7",
tag = "qty"
});
Console.WriteLine(Zip(Split(source, fields), fields));
Console.WriteLine(ReplaceRegex(source, fields));
}
static IEnumerable<string> Split(string source, IEnumerable<Field> fields)
{
var index = 0;
foreach (var field in fields.OrderBy(q => q.pos))
{
yield return source.Substring(index, field.pos - index);
index = field.pos + field.len;
}
yield return source.Substring(index, source.Length - index);
}
static string Zip(IEnumerable<string> splitted, IEnumerable<Field> fields)
{
var items = splitted.Zip(fields, (l, r) => new string[] { l, r.value }).SelectMany(q => q).ToList();
items.Add(splitted.Last());
return string.Concat(items);
}
static string ReplaceRegex(string source, IEnumerable<Field> fields)
{
var fieldsDict = fields.ToDictionary(q => q.tag);
var re = new Regex(@"\[(\w+)\]");
return re.Replace(source, new MatchEvaluator((m) => fieldsDict[m.Groups[1].Value].value));
}
}
順便說一句,最好是使用正則表達式替換特殊的用戶標記,如[price],[qty]?
「*由於我將這麼做很多次,我希望它儘可能快*」。定義'很多'?每個按鈕點擊幾千次?那麼這是過早的優化。夜間批量工作每小時幾百萬次?此外,還有一些不成熟的優化(每小時以約278次/秒的速度運行一個小時)。如果這個字符串操作變成瓶頸,我會驚呆了。 – 2010-08-11 14:49:23
是的,但如果可能的話,編寫高效的代碼仍然很不錯。我只是檢查我沒有做可怕的低效率事情。作爲一名.NET開發人員,您總是會聽到有關錯誤的字符串操作會如何影響性能的問題。 該計劃的核心實際上將用於多個項目。第一個涉及文件轉換。輸出文件包含基於輸入文件生成的值。我相信每個輸入文件可能包含數百個(如果不是數千個)記錄。但使用此代碼的未來應用程序可能會有更重的工作負載。 – James 2010-08-11 15:16:12
在將字段附加到流中時,您可能會更好,而不是構建字符串並編寫它。使用'System.IO.StringWriter',你總是可以得到輸出爲一個字符串,如果你需要它出於任何原因。 – 2010-08-11 15:26:10