C# 过符号字符的分析例程相对较慢

C# 过符号字符的分析例程相对较慢,c#,substring,C#,Substring,我试图使用NETFramework4.6.1使附带的子例程性能更高,尽管我最终将把它移植到NETCore2.2 解析文件时,它可能运行多达250000次 使用VisualStudioPerformanceAnalyzer,我发现这个例程在整个解析过程中似乎有相当高的相对成本 该代码是解析程序的一部分,该程序的输入是一个二进制文件,其中包含一些非常旧的记录格式,其中包含过符号数字 过签名数字(背景) 如果数字为负数,为了节省空间,最后一位数字将改为字母,而不是减号。这是一个非常古老的标准,可以追溯

我试图使用NETFramework4.6.1使附带的子例程性能更高,尽管我最终将把它移植到NETCore2.2

解析文件时,它可能运行多达250000次

使用VisualStudioPerformanceAnalyzer,我发现这个例程在整个解析过程中似乎有相当高的相对成本

该代码是解析程序的一部分,该程序的输入是一个二进制文件,其中包含一些非常旧的记录格式,其中包含过符号数字

过签名数字(背景)

如果数字为负数,为了节省空间,最后一位数字将改为字母,而不是减号。这是一个非常古老的标准,可以追溯到计算机内存有限,性能需要固定宽度的记录时

解析时,我需要将最后一个字母转换回一个数字,并使数字为负数

例程输入和输出的一些示例

00056K=-562

00032N=-325

当前代码(慢速)


切换索引字符<代码>子字符串实际上是一个新的
字符串,速度很慢:

switch (overSignedString[Length - 1])
{
    case ' ':
        return 0;
    case "J":
        return ...

您可能希望阅读,看看是否值得解析每个大小写中的字符串,以避免
Convert
。有更快的方法。

切换索引字符<代码>子字符串实际上是一个新的
字符串,速度很慢:

switch (overSignedString[Length - 1])
{
    case ' ':
        return 0;
    case "J":
        return ...

您可能希望阅读,看看是否值得解析每个大小写中的字符串,以避免
Convert
。有更快的方法。

不确定下面的解决方案是否完全等同于您的解决方案,但至少应该给您一个关于如何创建非常快速的字符串到数字解析器的提示

    private int ConvertOverSign(string overSignedString)
    {
        if (overSignedString == " ") return 0;

        int value = 0;
        for (int i = 0; i < overSignedString.Length; i++)
        {
            char ch = overSignedString[i];
            switch (ch)
            {
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    value = value * 10 + (ch - 0x30);
                    break;

                case '!':
                    value *= 10;
                    return -value;

                case 'J':
                case 'K':
                case 'L':
                case 'M':
                case 'N':
                case 'O':
                case 'P':
                case 'Q':
                case 'R':
                    value = value * 10 + (ch - 'I');
                    return -value;
            }
        }
        return value;
    }
private int ConvertOverSign(字符串overSignedString)
{
if(overSignedString==“”)返回0;
int值=0;
for(int i=0;i

请记住,如果您需要性能,字符串操作(例如子字符串)通常非常繁重。

不确定下面的解决方案是否完全等同于您的解决方案,但至少应该给您一个提示,说明如何创建一个非常快的字符串到数字解析器

    private int ConvertOverSign(string overSignedString)
    {
        if (overSignedString == " ") return 0;

        int value = 0;
        for (int i = 0; i < overSignedString.Length; i++)
        {
            char ch = overSignedString[i];
            switch (ch)
            {
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    value = value * 10 + (ch - 0x30);
                    break;

                case '!':
                    value *= 10;
                    return -value;

                case 'J':
                case 'K':
                case 'L':
                case 'M':
                case 'N':
                case 'O':
                case 'P':
                case 'Q':
                case 'R':
                    value = value * 10 + (ch - 'I');
                    return -value;
            }
        }
        return value;
    }
private int ConvertOverSign(字符串overSignedString)
{
if(overSignedString==“”)返回0;
int值=0;
for(int i=0;i

请记住,如果您需要性能,字符串操作(例如子字符串)通常会很繁重。

您的方法很慢,因为它会生成大量字符串垃圾

您可以通过比较字符而不是字符串来改进它,并执行结果整数的乘法而不是追加字符串,以及使用查找而不是开关:

private Dictionary<char, int> _additions = new Dictionary<char, int>
{
    { '!', 0 },
    { 'J', 1 },
    { 'K', 2 },
    { 'L', 3 },
    { 'M', 4 },
    { 'N', 5 },
    { 'O', 6 },
    { 'P', 7 },
    { 'Q', 8 },
    { 'R', 9 },
};

private int ConvertOverSign(string overSignedString)
{
    var lastChar = overSignedString[overSignedString.Length -1];

    if (lastChar == ' ')
    {
        return 0;
    }

    if (!_additions.TryGetValue(lastChar, out int addition))
    {
        return Convert.ToInt32(overSignedString);
    }

    var result = (Convert.ToInt32(overSignedString.Substring(0, overSignedString.Length - 1)) * -10) - addition;
    return result;
}
private Dictionary\u additions=新字典
{
{ '!', 0 },
{'J',1},
{'K',2},
{'L',3},
{'M',4},
{'N',5},
{'O',6},
{'P',7},
{'Q',8},
{'R',9},
};
专用int ConvertOverSign(字符串overSignedString)
{
var lastChar=overSignedString[overSignedString.Length-1];
如果(lastChar='')
{
返回0;
}
if(!\u additions.TryGetValue(lastChar,out int addition))
{
返回Convert.ToInt32(overSignedString);
}
var result=(Convert.ToInt32(overSignedString.Substring(0,overSignedString.Length-1))*-10-加法;
返回结果;
}

您的方法很慢,因为它会生成大量字符串垃圾

您可以通过比较字符而不是字符串来改进它,并执行结果整数的乘法而不是追加字符串,以及使用查找而不是开关:

private Dictionary<char, int> _additions = new Dictionary<char, int>
{
    { '!', 0 },
    { 'J', 1 },
    { 'K', 2 },
    { 'L', 3 },
    { 'M', 4 },
    { 'N', 5 },
    { 'O', 6 },
    { 'P', 7 },
    { 'Q', 8 },
    { 'R', 9 },
};

private int ConvertOverSign(string overSignedString)
{
    var lastChar = overSignedString[overSignedString.Length -1];

    if (lastChar == ' ')
    {
        return 0;
    }

    if (!_additions.TryGetValue(lastChar, out int addition))
    {
        return Convert.ToInt32(overSignedString);
    }

    var result = (Convert.ToInt32(overSignedString.Substring(0, overSignedString.Length - 1)) * -10) - addition;
    return result;
}
private Dictionary\u additions=新字典
{
{ '!', 0 },
{'J',1},
{'K',2},
{'L',3},
{'M',4},
{'N',5},
{'O',6},
{'P',7},
{'Q',8},
{'R',9},
};
专用int ConvertOverSign(字符串overSignedString)
{
var lastChar=overSignedString[overSignedString.Length-1];
如果(lastChar='')
{
返回0;
}
如果(!\u additions.TryGetValue(