【发布时间】:2011-03-21 03:54:57
【问题描述】:
我希望就如何加快以下功能获得一些建议。具体来说,我希望找到一种更快的方法将数字(主要是双精度数,IIRC 里面有一个 int)转换为字符串以存储为 Listview 子项。就目前而言,这个函数需要 9 秒来处理 16 个订单!绝对疯了,特别是考虑到除了处理 DateTimes 的调用之外,这一切都只是字符串转换。
我认为列表视图项的实际显示速度很慢,所以我做了一些研究,发现将所有子项添加到数组中并使用 Addrange 比一次添加一项要快得多。我实施了更改,但没有更好的速度。
然后我在每条线路周围添加了一些秒表,以准确缩小导致减速的原因;不出所料,对 datetime 函数的调用是最慢的,但我很惊讶地看到 string.format 调用也非常慢,考虑到它们的数量,占了我大部分时间。
private void ProcessOrders(List<MyOrder> myOrders)
{
lvItems.Items.Clear();
marketInfo = new MarketInfo();
ListViewItem[] myItems = new ListViewItem[myOrders.Count];
string[] mySubItems = new string[8];
int counter = 0;
MarketInfo.GetTime();
CurrentTime = MarketInfo.CurrentTime;
DateTime OrderIssueDate = new DateTime();
foreach (MyOrder myOrder in myOrders)
{
string orderIsBuySell = "Buy";
if (!myOrder.IsBuyOrder)
orderIsBuySell = "Sell";
var listItem = new ListViewItem(orderIsBuySell);
mySubItems[0] = (myOrder.Name);
mySubItems[1] = (string.Format("{0:g}", myOrder.QuantityRemaining) + "/" + string.Format("{0:g}", myOrder.InitialQuantity));
mySubItems[2] = (string.Format("{0:f}", myOrder.Price));
mySubItems[3] = (myOrder.Local);
if (myOrder.IsBuyOrder)
{
if (myOrder.Range == -1)
mySubItems[4] = ("Local");
else
mySubItems[4] = (string.Format("{0:g}", myOrder.Range));
}
else
mySubItems[4] = ("N/A");
mySubItems[5] = (string.Format("{0:g}", myOrder.MinQuantityToBuy));
string IssueDateString = (myOrder.DateWhenIssued + " " + myOrder.TimeWhenIssued);
if (DateTime.TryParse(IssueDateString, out OrderIssueDate))
mySubItems[6] = (string.Format(MarketInfo.ParseTimeData(CurrentTime, OrderIssueDate, myOrder.Duration)));
else
mySubItems[6] = "Error getting date";
mySubItems[7] = (string.Format("{0:g}", myOrder.ID));
listItem.SubItems.AddRange(mySubItems);
myItems[counter] = listItem;
counter++;
}
lvItems.BeginUpdate();
lvItems.Items.AddRange(myItems.ToArray());
lvItems.EndUpdate();
}
这是来自示例运行的时间数据:
0: 166686
1:264779
2:273716
3:136698
4:587902
5:368816
6:955478
7:128981
其中数字等于数组的索引。与这些相比,所有其他行的刻度都非常低,可以忽略不计。
虽然我希望能够使用 string.format 的数字格式来获得漂亮的输出,但我希望能够在我的一生中加载更多的订单列表,所以如果有字符串的替代方案。格式更快,但没有花里胡哨,我完全赞成。
编辑:感谢所有建议 myOrder 类可能使用 getter 方法而不是像我最初想的那样实际存储变量的人。我检查了一下,果然,这就是我放慢速度的原因。尽管我无权访问该类来更改它,但我能够搭载方法调用来填充 myOrders 并将每个变量复制到同一调用中的列表中,然后在填充我的 Listview 时使用该列表。现在几乎立即填充。再次感谢。
【问题讨论】:
-
我将其重新标记为 .net 和 c#,我一眼就看出来了。希望没问题。
-
您期望的基准时间是多少?我非常怀疑使用
String.Format()会导致那 很多时间,它应该可以忽略不计。我会仔细看看你的MarketInfo方法调用。在我看来,您将要做一些 I/O,我怀疑这就是所有减速的原因。 -
您可能希望在代码示例中包含 MyOrder 类,或者至少明确 MyOrder 的属性是否只是小数/整数值,或者它们是否是可能在返回之前进行计算的 getter 方法一个值(因为这可能会影响对时间的解释)。
-
我实际上怀疑
ListView操作是缓慢的部分。如果您注释掉引用listItem的行,您的函数会加速吗?
标签: c# .net string string.format