我有一个实现异步SOAP的应用程序。每隔50-100ms,我将收到转换为SortedList<double,double>
对象的数据。我还有一个预定义的IList<double>
,其中包含SortedList
中所有可能的密钥。
我需要遍历IList
并检查SortedList
是否包含该密钥。如果是,我将该值写入csv字符串;如果没有,我将0.0写入csv字符串。
注意: IList有400个密钥。 SortedList通常远小于400,最多约100个。
string MyText = timestamp.ToString("HH:mm:ss");
for (int i = 0; i < AllKeys.Count; i++)
{
double info;
if (MySortedList.TryGetValue(AllKeys[i], out info))
{
MyText += "," + info;
}
else
{
MyText += ",0.0";
}
}
MyText += "\n";
File.AppendAllText(filePath, MyText);
我目前正在使用上面的代码创建csv字符串,然后再将其写入我的文件。但是,我发现此代码滞后于我的应用程序。
我需要帮助提高效率,以便存储传入数据的时间少于50毫秒。其他一些事情:
编辑:我使用Conrad建议制作StreamWriter对象解决了我的性能问题。我只是创建了一个静态StreamWriter对象,并在通信终止时关闭StreamWriter之前将所有文本写入其中。
答案 0 :(得分:2)
以下是一些想法。
1)使用StreamWriter来代替文件。这比写入内存然后写入文件的两步要快。
2)如果一切可能并行化工作。例如,如果您可以使用一个线程来处理消息,而另一个线程则可以编写消息。
3)我不认为LINQ的目的是提高性能,但更容易操作数据
答案 1 :(得分:0)
我确信我没有提出最有效的算法,但至少这是一个起点。如果没有别的,你会注意到使用StringBuilder
,而不是连接字符串。仅这一点就可能为您带来一些好处。
此算法假定SortedList键和“data”列表以相同的方式(从低到高)排序。
var textBuilder = new StringBuilder(timestamp.ToString("HH:mm:ss"));
var index = 0;
foreach(double key in data.Keys)
{
while(Allkeys[index] < key)
{
textBuilder.Append(",0.0");
index++;
}
textBuilder.Append(",").Append(data[key]);
index++;
}
MyText = textBuilder.Append(@"\n").ToString();
只要看一下上面的内容,我肯定会有一个错误,但不确定在没有花费更多时间和/或测试的情况下会发生什么或哪些错误。
可能的LINQ解决方案更具说明性:
var textBuilder = new StringBuilder(timestamp.ToString("HH:mm:ss"));
var values = Allkeys.Select(
key => data.ContainsKey(key) ? data[key].ToString() : "0.0")
.ToArray();
var data = String.Join(",", values);
var MyText = textBuilder.Append(data).Append(@"\n").ToString();
使用Aggregate扩展方法可以在LINQ表达式中包含更多内容,但是你必须在累加器中使用字符串连接,所以我没有在这里显示。
答案 2 :(得分:0)
我同意Conrad的回答 - 还有一个提高性能的想法是进行反向查找,即从SortedList获取每个元素并在其他列表中进行查找(当然,我建议使用字典而不是列表以便更快查找)。