Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# String.format速度慢,需要更快的替代方案_C#_.net_String_String.format - Fatal编程技术网

C# String.format速度慢,需要更快的替代方案

C# String.format速度慢,需要更快的替代方案,c#,.net,string,string.format,C#,.net,String,String.format,我希望得到一些关于如何加速以下功能的建议。具体地说,我希望找到一种更快的方法将数字(大部分是双精度的,IIRC中有一个int)转换成字符串存储为Listview子项。目前,此功能需要9秒来处理16个订单!绝对疯狂,尤其是考虑到除了处理DateTimes的调用之外,这一切都只是字符串转换 我认为listview项目的实际显示很慢,所以我做了一些研究,发现将所有子项目添加到数组并使用Addrange比一次添加一个项目快得多。我实施了改变,但没有得到更好的速度 然后,我在每条生产线周围加上了一些秒表,

我希望得到一些关于如何加速以下功能的建议。具体地说,我希望找到一种更快的方法将数字(大部分是双精度的,IIRC中有一个int)转换成字符串存储为Listview子项。目前,此功能需要9秒来处理16个订单!绝对疯狂,尤其是考虑到除了处理DateTimes的调用之外,这一切都只是字符串转换

我认为listview项目的实际显示很慢,所以我做了一些研究,发现将所有子项目添加到数组并使用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();
    }
private void ProcessOrders(列出myorder)
{
lvItems.Items.Clear();
marketInfo=新的marketInfo();
ListViewItem[]myItems=新ListViewItem[myOrders.Count];
string[]mySubItems=新字符串[8];
int计数器=0;
MarketInfo.GetTime();
CurrentTime=MarketInfo.CurrentTime;
DateTime OrderIssueDate=新的日期时间();
foreach(MyOrder中的MyOrder)
{
字符串orderIsBuySell=“Buy”;
如果(!myOrder.IsBuyOrder)
orderIsBuySell=“Sell”;
var listItem=新的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)
{
如果(myOrder.Range==-1)
mySubItems[4]=(“本地”);
其他的
mySubItems[4]=(string.Format(“{0:g}”,myOrder.Range));
}
其他的
mySubItems[4]=(“不适用”);
mySubItems[5]=(string.Format(“{0:g}”,myOrder.MinQuantityToBuy));
字符串IssuedTestRing=(myOrder.DateWhenIssued+“”+myOrder.TimeWhenIssued);
if(DateTime.TryParse(IssuedTestRing,OutOrderIssuedate))
mySubItems[6]=(string.Format(MarketInfo.ParseTimeData(CurrentTime、ordersissueDate、myOrder.Duration));
其他的
mySubItems[6]=“获取日期时出错”;
mySubItems[7]=(string.Format(“{0:g}”,myOrder.ID));
listItem.SubItems.AddRange(mySubItems);
myItems[计数器]=列表项;
计数器++;
}
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的数字格式进行漂亮的输出,但我希望能够在我的有生之年加载更多的订单列表,因此,如果有一种比string.format快得多但没有铃声和口哨的替代方法,我完全赞成



编辑:感谢所有建议myOrder类使用getter方法的人,而不是像我最初认为的那样实际存储变量。我检查了一下,果然,这就是我减速的原因。虽然我无法访问该类来更改它,但我能够借助方法调用来填充myOrder,并将每个变量复制到同一调用中的列表中,然后在填充Listview时使用该列表。现在几乎立刻就有人来了。再次感谢。

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

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

替换

string.Format("{0:g}", myOrder.MinQuantityToBuy)


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

我将所有string.format调用放入一个循环中,并能够在一秒钟内将它们全部运行100万次,因此您的问题不是string.format…而是代码中的其他地方


也许这些属性中的某些在其getter方法中具有逻辑性?如果你注释掉listview的所有代码,你会得到什么样的时间?

这绝对不是字符串格式让你慢下来。怀疑从myOrder访问属性

在其中一个format调用中,尝试声明几个局部变量并将它们设置为您尝试格式化的属性,然后将这些局部变量传递给yoru string.format和retime。您可能会发现string.Format现在以闪电般的速度运行

现在,属性访问通常不需要很多时间来运行。但是,我看到一些类记录了每个属性访问(用于审计跟踪)。检查是否存在这种情况,以及是否有操作阻止您的财产访问权立即返回

如果有某个操作持有属性访问权,请尝试将这些操作排队(例如,将日志调用排队),并让后台线程执行这些操作。立即返回属性访问权限

此外,切勿将运行缓慢的代码(例如,复杂的计算)放入属性访问器/获取器,也不要将具有副作用的代码放入属性访问器/获取器。使用该类的人不会意识到它将被删除
myOrder.MinQuantityToBuy.ToString("g")
    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;
        // ReSharper disable TooWideLocalVariableScope
        DateTime orderIssueDate;
        // ReSharper restore TooWideLocalVariableScope

        foreach (MyOrder myOrder in myOrders)
        {
            string orderIsBuySell = myOrder.IsBuyOrder ? "Buy" : "Sell";
            var listItem = new ListViewItem(orderIsBuySell);

            mySubItems[0] = myOrder.Name;
            mySubItems[1] = string.Format("{0:g}/{1:g}", myOrder.QuantityRemaining, myOrder.InitialQuantity);
            mySubItems[2] = myOrder.Price.ToString("f");
            mySubItems[3] = myOrder.Local;

            if (myOrder.IsBuyOrder)
                mySubItems[4] = myOrder.Range == -1 ? "Local" : myOrder.Range.ToString("g");
            else
                mySubItems[4] = "N/A";

            mySubItems[5] = myOrder.MinQuantityToBuy.ToString("g");

            // This code smells:
            string issueDateString = string.Format("{0} {1}", myOrder.DateWhenIssued, myOrder.TimeWhenIssued);
            if (DateTime.TryParse(issueDateString, out orderIssueDate))
                mySubItems[6] = MarketInfo.ParseTimeData(CurrentTime, orderIssueDate, myOrder.Duration);
            else
                mySubItems[6] = "Error getting date";

            mySubItems[7] = myOrder.ID.ToString("g");

            listItem.SubItems.AddRange(mySubItems);
            myItems[counter] = listItem;
            counter++;
        }
        lvItems.BeginUpdate();
        lvItems.Items.AddRange(myItems.ToArray());
        lvItems.EndUpdate();
    }