.net 要列出的字符串<;双倍>;

.net 要列出的字符串<;双倍>;,.net,string,parsing,.net,String,Parsing,我有一个由一系列用空格或逗号分隔的实数组成的函数,如下所示: “645.974255.478 645.973255.468 645.97 0 233.54 21” 我想解析我的字符串并用它的数字填充a。我正试图找到最快的方法来完成这项任务。到目前为止,我已经尝试了以下方法,有一个double列表,并对字符串进行了十万次解析 List<double> MyList = new List<double>(250); 使用C++/CLI的非托管代码:~7.5[s] stat

我有一个由一系列用空格或逗号分隔的实数组成的函数,如下所示:

“645.974255.478 645.973255.468 645.97 0 233.54 21”

我想解析我的字符串并用它的数字填充a。我正试图找到最快的方法来完成这项任务。到目前为止,我已经尝试了以下方法,有一个double列表,并对字符串进行了十万次解析

List<double> MyList = new List<double>(250);
  • 使用C++/CLI的非托管代码:~7.5[s]

    static void UsingUnmanagedCode(wchar_t* points, List<double> ^MyList)
    {
        static char buffer[MAX_CHARS];
        wcstombs(buffer, points, MAX_CHARS);
        char *start = buffer, *ptr = buffer;
    
        for(; *ptr; ++ptr)
        {
            if(*ptr == ',')
                *ptr = ' ';
        }
    
        while(*(--ptr) == ' ')
            *ptr = '\0';
    
        char *pEnd;
        MyList->Add(strtod(start, &pEnd));
    
        while(*pEnd)
        {
            char *pStart = pEnd;
            MyList->Add(strtod(pStart, &pEnd));
        }
    }
    

  • 有更好的选择吗?

    如果速度对您至关重要,您可能需要评估程序的设计,看看是否可以“动态”拆分字符串


    例如,字符串是如何进入程序的?要使任何算法超高效,您最好的选择(据我所知)是尝试将您的操作压缩到单个循环中。。。单个循环自动比多个循环快。要做到这一点,一个简单的方法是“监听”输入的数据,一个字符一个字节一个字节,一旦你意识到自己有一个有效的实数,就在列表中添加一个有效的实数。

    很少有情况下,获取字符串的成本不会比解析它高出几个数量级。I/O速度慢。使用
    String.Split
    的版本比其他任何版本都快,代码也更简单。那就是我要去的那个。我从他那里得到了线。“动态”是什么意思?当您从外部源(如XML、SQL等)获取数据时,您就是在“流”数据。很多时候,.NET framework会为您处理流媒体,因此您只能得到整个字符串,而没有其他内容,但是您可以告诉.NET让您自己处理流媒体。这样做使您有机会在数据流入时创建列表,而不必在已经生成字符串后再创建列表(从而避免第二个循环)。对于XPath,您应该能够创建自己的IXMLSerializable实现(),其中-而不是调用XmlReader.ReadString()您可以创建自己的方法来读取字符串,作为读取字符串的一部分,您还可以创建列表。这项工作绝对不是为业余爱好者准备的,但是如果您非常关心性能,那么您唯一的选择就是直接找到源代码并自己动手。我使用解析XML文件,如何跨节点读取属性而不是使用该类?您需要放弃XPath方法,创建自己的XML序列化程序类,就像我说的那样。XPath完全是为了方便,而不是效率。如果可能的话,看看您是否可以通过XML以外的任何其他方式获取数据,因为这也不知道是否有效率。在不了解您的情况下,我个人会接受Stirng.Split的效率,或者提出一个新的数据层(如果可能的话)。
    static void UsingUnmanagedCode(wchar_t* points, List<double> ^MyList)
    {
        static char buffer[MAX_CHARS];
        wcstombs(buffer, points, MAX_CHARS);
        char *start = buffer, *ptr = buffer;
    
        for(; *ptr; ++ptr)
        {
            if(*ptr == ',')
                *ptr = ' ';
        }
    
        while(*(--ptr) == ' ')
            *ptr = '\0';
    
        char *pEnd;
        MyList->Add(strtod(start, &pEnd));
    
        while(*pEnd)
        {
            char *pStart = pEnd;
            MyList->Add(strtod(pStart, &pEnd));
        }
    }
    
    MyList.Clear();
    
        fixed (char* fixPointsPtr = Points)
        {
            char* ptr = fixPointsPtr;
    
            while (*ptr != '\0')
            {
                if ((*ptr < '0' || *ptr > '9') && *ptr != '-' && *ptr != '.')
                {
                    MyList.Add(double.Parse(strBuild.ToString(0, strBuild.Length), NumberStyles.AllowDecimalPoint));
                    strBuild.Length = 0;
                }
    
                else
                    strBuild.Append(*ptr);
    
                ++ptr;
            }
        }
    
    MyList.Clear();
    
    foreach (string point in Points.Split(Separators, StringSplitOptions.RemoveEmptyEntries))
            MyList.Add(double.Parse(point, NumberStyles.AllowDecimalPoint));