String.format很慢,需要更快的替代方案

Jac*_*lon 5 .net c# string string.format

我希望得到一些关于如何加速以下功能的建议.具体来说,我希望找到一种更快的方法来将数字(大多数是双数,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();
    }
Run Code Online (Sandbox Code Playgroud)

以下是样本运行的时间数据:
0:166686
1:264779
2:273716
3:136698
4:587902
5:368816
6:955478
7: 128981

数字等于数组索引的位置.所有其他品系的蜱虫数量都很低,与此相比可以忽略不计.

虽然我希望能够使用string.format的数字格式来获得漂亮的输出,但我希望能够在我的生命周期内加载一个订单列表,所以如果有一个替代string.format的话更快,但没有花里胡哨,我全都是为了它.


编辑:感谢所有建议myOrder类可能使用getter方法而不是按照我原先的想法实际存储变量的人.我查了一下,果然,这是我减速的原因.虽然我没有访问类来更改它,但我能够捎带到方法调用以填充myOrders并将每个变量复制到同一调用中的列表中,然后在填充Listview时使用该列表.现在几乎立即填充.再次感谢.

Joe*_*nos 3

我发现很难相信简单的 string.Format 调用会导致您的缓慢问题 - 它通常是一个非常快的调用,特别是对于像您大多数人这样简单的调用。

但有一件事可能会给你几微秒的时间......

代替

string.Format("{0:g}", myOrder.MinQuantityToBuy)
Run Code Online (Sandbox Code Playgroud)

myOrder.MinQuantityToBuy.ToString("g")
Run Code Online (Sandbox Code Playgroud)

当您执行单个值的直接格式时,这将起作用,但对于更复杂的调用没有任何好处。