gpt4 book ai didi

c# - 没有实际解析的TryParse或任何其他具有性能优势的文本格式检查选项

转载 作者:行者123 更新时间:2023-11-30 12:24:19 24 4
gpt4 key购买 nike

我目前正在制作自己的库,称为TextCheckerExtension,该库主要尝试在进一步处理之前检查文本格式(如下所示的简短代码段)。

现在,我知道我在做什么与ParseTryParse十分相似。此和所有Parse之间的唯一区别是,它不会生成任何已解析的对象。它只是检查字符串。

我的问题是:


ParseTryParse均生成已解析的对象。万一我们只想检查string输入的有效性,生成解析对象的开销真的会影响方法的性能吗(这种情况下的任何示例)?也就是说,自行创建的检查方法不会生成解析的对象会更快。
C#中有没有其他替代方法(内置)可以在不生成解析对象的情况下检查各种字符串格式的有效性?
Regex可以替代吗?


任何对此事的投入将不胜感激。



public static bool IsPureHex(string str) {
return IsPureHex(str, int.MaxValue); //assuming very high value!
}

public static bool IsPureHex(string str, int maxNibble) {
if (str.Length > maxNibble) //if the length is violated, it is considered failed
return false;
for (int i = 0; i < Math.Min(maxNibble, str.Length); i++)
if (!((char.IsDigit(str, i)) || ((str[i] >= 'A') && (str[i] <= 'F')) || ((str[i] >= 'a') && (str[i] <= 'f'))))
return false;
return true;
}

public static bool IsHex(string str) {
if (str.Length <= 2 || (str[0] != '0') || !((str[1] == 'x') || (str[1] == 'X'))) //Check input validity
return false;
for (int i = 2; i < str.Length; i++)
if (!((char.IsDigit(str, i)) || ((str[i] >= 'A') && (str[i] <= 'F')) || ((str[i] >= 'a') && (str[i] <= 'f'))))
return false;
return true;
}

public static bool IsFloat(string str) { //another criterion for float, giving "f" in the last part?
int dotCounter = 0;
for (int i = 0; i < str.Length; i++) { //Check if it is float
if (!(char.IsDigit(str, i)) && (str[i] != '.'))
return false;
else if (str[i] == '.')
++dotCounter; //Increase the dotCounter whenever dot is found
if (dotCounter > 1) //If there is more than one dot for whatever reason, return error
return false;
}
return dotCounter == 1 && str.Length > 1;
}

public static bool IsDigitsOnly(string str) {
foreach (char c in str)
if (c < '0' || c > '9')
return false;
return str.Length >= 1; //there must be at least one character here to continue
}

public static bool IsInt(string str) { //is not designed to handle null input or empty string
return str[0] == '-' && str.Length > 1 ? IsDigitsOnly(str.Substring(1)) : IsDigitsOnly(str);
}

最佳答案

它的确有所作为。

令我惊讶的是:出于好奇我继续进行此项目时,我发现进行实际的分析并仅检查字符串是否具有某种格式确实会在时间性能上产生重大差异。

在下面的实验中,通过创建没有解析器的检查器,与使用内置的TryParse相比,我们可以获得33.77%至58.26%的时间增益。此外,我还将扩展名与VB.Net dll中的IsNumeric Microsoft.VisualBasic.Information进行了比较。

以下是(1)测试代码,(2)测试方案,(3)测试代码和(4)测试结果(在必要时在各部分中添加注释):



测试代码:

这是经过测试的代码,我的扩展名为Extension.Checker.Text。到目前为止,我只测试了通用integerfloat/double(带/不带点-也许更好地称为分数级数)的方案。泛型integer表示未选中最大值和最小值范围(例如8位带符号整数的-128到127)。此代码仅是确定文本是否为integer,而不是人们理解其范围,而无需理解。 float/double也是一样。

this帖子相比,在发布此答案之前,其答案有400多个投票,我相信可以肯定地说,通常我们将使用int.TryParse来测试文本是否为integer,通用-2e9文本的第一次尝试(尽管其范围仅限于2e9integer)。 Some other posts也显示相同的趋势。我们从这些帖子中可以看到的另一种方法是通过Visual Basic IsNumeric进行检查。因此,我也在benchmarking中包含了该方法。

public static bool IsFloatOrDoubleByDot(string str) { //another criterion for float, giving "f" in the last part?
if (string.IsNullOrWhiteSpace(str))
return false;
int dotCounter = 0;
for (int i = str[0] == '-' ? 1 : 0; i < str.Length; i++) { //Check if it is float
if (!(char.IsDigit(str, i)) && (str[i] != '.'))
return false;
else if (str[i] == '.')
++dotCounter; //Increase the dotCounter whenever dot is found
if (dotCounter > 1) //If there is more than one dot for whatever reason, return error
return false;
}
return dotCounter == 0 || dotCounter == 1 && str.Length > 1;
}

public static bool IsDigitsOnly(string str) {
foreach (char c in str)
if (c < '0' || c > '9')
return false;
return str.Length >= 1; //there must be at least one character here to continue
}

public static bool IsInt(string str) { //is not designed to handle null input or empty string
if (string.IsNullOrWhiteSpace(str))
return false;
return str[0] == '-' && str.Length > 1 ? IsDigitsOnly(str.Substring(1)) : IsDigitsOnly(str);
}






测试方案:

到目前为止,我已经测试了四种不同的方案:


整数(在int.TryParse的可分析范围内)
包含 dot的float文本(最大7位精度,在float.TryParse所能精确解析的范围内)
包含 dot的双精度文本(最大11位精度,在double.TryParse的可精确解析范围内)
整数文本读取为float / double文本(在double.TryParse的可解析范围内)


对于每种情况,我有四种情况要测试:


有效的正值文字
有效的负值文字
无效的正值文字
无效的负值文字


对于每种情况,我通过以下方式测试了进行检查所需的时间:


合适的 TryParse
合适的 Extension.Checker.Text
Visual Basic IsNumeric
其他类型特定的技巧,例如用于整数的string.All(char.IsDigit)






测试代码:

为了测试上述情况,我使用以下数据:

string intpos = "1342517340";
string intneg = "-1342517340";
string intfalsepos = "134251734u";
string intfalseneg = "-134251734u";
string floatpos = "56.34251";
string floatneg = "-56.34251";
string floatfalsepos = "56.3425h";
string floatfalseneg = "-56.3425h";
string doublepos = "56.342515312";
string doubleneg = "-56.342515312";
string doublefalsepos = "56.34251531y";
string doublefalseneg = "-56.34251531y";
List<string> liststr = new List<string>() {
intpos, intneg, intfalsepos, intfalseneg,
floatpos, floatneg, floatfalsepos, floatfalseneg,
doublepos, doubleneg, doublefalsepos, doublefalseneg
};
List<string> liststrcode = new List<string>() {
"i+", "i-", "if+", "if-",
"f+", "f-", "ff+", "ff-",
"d+", "d-", "df+", "df-"
};
bool parsed = false; //to store checking result
int intval; //for int.TryParse result
float fval; //for float.TryParse result
double dval; //for double.TryParse result


文本代码的格式为。例子:


如果+ =整数假阳性
f- =浮动负数


我使用以下测试循环来获得每种情况下每种方法的时间性能:

//time snap
for (int i = 0; i < 10000000; ++i) //for integer case
parsed = int.TryParse(str, out intval); //built-in TryParse
//time snap
//Print the result
//time snap
for (int i = 0; i < 10000000; ++i)
parsed = Extension.Checker.Text.IsInt(str); //extension Text checker
//time snap
//Print the result
//time snap
for (int i = 0; i < 10000000; ++i)
parsed = Information.IsNumeric(str); //Microsoft.VisualBasic
//time snap
//Print the result
//time snap
for (int i = 0; i < 10000000; ++i)
parsed = str[0] == '-' ? str.Substring(1).All(char.IsDigit) : str.All(char.IsDigit); //misc methods
//time snap
//Print the result
//Print the result difference


使用笔记本电脑,每种方法的每个测试用例测试了多达1000万次迭代。

注意:请注意,我的 Extension.Checker.Text的行为与内置的 TryParse并不完全等效,例如检查字符串的数值范围或使用其他可能接受 TryParse格式的格式的字符串但不是我的情况。这是因为 Extension.Checker.Text的主要目的不是一定要将C#中的给定文本转换为内置 TryParse的某些数据类型。这就是我的 Extension.Checker.Text的重点。在时间上的好处方面,这里所做的比较仅仅是为了比较(1)使用(2)在不需要我们的结果的情况下可以进行的扩展方法来检查某些文本格式的 popular wayTryParse,但仅当文本为特定格式时才可以。与VB IsNumeric进行比较时也是如此





测试结果:

我打印出了 parse/check结果,以确保扩展名与给定情况下的内置 TryParseVB.Net IsNumeric和其他替代技巧相同。我还会打印原始文本,以方便阅读/检查。然后,通过测试之间的时间间隔,我可以获得每个测试用例的时间性能和时差,我也将其打印出来。但是,时间增益比较仅使用 TryParse完成。这是完整的结果。

[2016-01-05 06:04:25.466 UTC] Integer:
[2016-01-05 06:04:26.999 UTC] TryParse i+: 1531 ms Result: True Text: 1342517340
[2016-01-05 06:04:27.639 UTC] Extension i+: 639 ms Result: True Text: 1342517340
[2016-01-05 06:04:30.345 UTC] VB.IsNumeric i+: 2705 ms Result: True Text: 1342517340
[2016-01-05 06:04:31.468 UTC] All is digit i+: 1124 ms Result: True Text: 1342517340
[2016-01-05 06:04:31.469 UTC] Gain on TryParse i+: 892 ms Percent: -58.26%
[2016-01-05 06:04:31.469 UTC]
[2016-01-05 06:04:32.996 UTC] TryParse i-: 1527 ms Result: True Text: -1342517340
[2016-01-05 06:04:33.846 UTC] Extension i-: 849 ms Result: True Text: -1342517340
[2016-01-05 06:04:36.413 UTC] VB.IsNumeric i-: 2566 ms Result: True Text: -1342517340
[2016-01-05 06:04:37.693 UTC] All is digit i-: 1280 ms Result: True Text: -1342517340
[2016-01-05 06:04:37.694 UTC] Gain on TryParse i-: 678 ms Percent: -44.40%
[2016-01-05 06:04:37.694 UTC]
[2016-01-05 06:04:39.058 UTC] TryParse if+: 1364 ms Result: False Text: 134251734u
[2016-01-05 06:04:39.845 UTC] Extension if+: 786 ms Result: False Text: 134251734u
[2016-01-05 06:04:42.436 UTC] VB.IsNumeric if+: 2590 ms Result: False Text: 134251734u
[2016-01-05 06:04:43.540 UTC] All is digit if+: 1103 ms Result: False Text: 134251734u
[2016-01-05 06:04:43.540 UTC] Gain on TryParse if+: 578 ms Percent: -42.38%
[2016-01-05 06:04:43.540 UTC]
[2016-01-05 06:04:44.937 UTC] TryParse if-: 1397 ms Result: False Text: -134251734u
[2016-01-05 06:04:45.745 UTC] Extension if-: 807 ms Result: False Text: -134251734u
[2016-01-05 06:04:48.275 UTC] VB.IsNumeric if-: 2530 ms Result: False Text: -134251734u
[2016-01-05 06:04:49.541 UTC] All is digit if-: 1267 ms Result: False Text: -134251734u
[2016-01-05 06:04:49.542 UTC] Gain on TryParse if-: 590 ms Percent: -42.23%
[2016-01-05 06:04:49.542 UTC]
[2016-01-05 06:04:49.542 UTC] Float by Dot:
[2016-01-05 06:04:51.136 UTC] TryParse f+: 1594 ms Result: True Text: 56.34251
[2016-01-05 06:04:51.967 UTC] Extension f+: 830 ms Result: True Text: 56.34251
[2016-01-05 06:04:54.328 UTC] VB.IsNumeric f+: 2360 ms Result: True Text: 56.34251
[2016-01-05 06:04:54.329 UTC] Time Gain f+: 764 ms Percent: -47.93%
[2016-01-05 06:04:54.329 UTC]
[2016-01-05 06:04:55.962 UTC] TryParse f-: 1634 ms Result: True Text: -56.34251
[2016-01-05 06:04:56.790 UTC] Extension f-: 827 ms Result: True Text: -56.34251
[2016-01-05 06:04:59.102 UTC] VB.IsNumeric f-: 2313 ms Result: True Text: -56.34251
[2016-01-05 06:04:59.103 UTC] Time Gain f-: 807 ms Percent: -49.39%
[2016-01-05 06:04:59.103 UTC]
[2016-01-05 06:05:00.623 UTC] TryParse ff+: 1519 ms Result: False Text: 56.3425h
[2016-01-05 06:05:01.429 UTC] Extension ff+: 802 ms Result: False Text: 56.3425h
[2016-01-05 06:05:03.730 UTC] VB.IsNumeric ff+: 2301 ms Result: False Text: 56.3425h
[2016-01-05 06:05:03.730 UTC] Time Gain ff+: 717 ms Percent: -47.20%
[2016-01-05 06:05:03.731 UTC]
[2016-01-05 06:05:05.312 UTC] TryParse ff-: 1581 ms Result: False Text: -56.3425h
[2016-01-05 06:05:06.147 UTC] Extension ff-: 835 ms Result: False Text: -56.3425h
[2016-01-05 06:05:08.485 UTC] VB.IsNumeric ff-: 2337 ms Result: False Text: -56.3425h
[2016-01-05 06:05:08.486 UTC] Time Gain ff-: 746 ms Percent: -47.19%
[2016-01-05 06:05:08.486 UTC]
[2016-01-05 06:05:08.487 UTC] Double by Dot:
[2016-01-05 06:05:10.341 UTC] TryParse d+: 1854 ms Result: True Text: 56.342515312
[2016-01-05 06:05:11.492 UTC] Extension d+: 1151 ms Result: True Text: 56.342515312
[2016-01-05 06:05:14.035 UTC] VB.IsNumeric d+: 2541 ms Result: True Text: 56.342515312
[2016-01-05 06:05:14.035 UTC] Time Gain d+: 703 ms Percent: -37.92%
[2016-01-05 06:05:14.036 UTC]
[2016-01-05 06:05:15.916 UTC] TryParse d-: 1879 ms Result: True Text: -56.342515312
[2016-01-05 06:05:17.051 UTC] Extension d-: 1133 ms Result: True Text: -56.342515312
[2016-01-05 06:05:19.542 UTC] VB.IsNumeric d-: 2492 ms Result: True Text: -56.342515312
[2016-01-05 06:05:19.543 UTC] Time Gain d-: 746 ms Percent: -39.70%
[2016-01-05 06:05:19.543 UTC]
[2016-01-05 06:05:21.210 UTC] TryParse df+: 1667 ms Result: False Text: 56.34251531y
[2016-01-05 06:05:22.315 UTC] Extension df+: 1104 ms Result: False Text: 56.34251531y
[2016-01-05 06:05:24.797 UTC] VB.IsNumeric df+: 2481 ms Result: False Text: 56.34251531y
[2016-01-05 06:05:24.798 UTC] Time Gain df+: 563 ms Percent: -33.77%
[2016-01-05 06:05:24.798 UTC]
[2016-01-05 06:05:26.509 UTC] TryParse df-: 1711 ms Result: False Text: -56.34251531y
[2016-01-05 06:05:27.596 UTC] Extension df-: 1086 ms Result: False Text: -56.34251531y
[2016-01-05 06:05:30.039 UTC] VB.IsNumeric df-: 2442 ms Result: False Text: -56.34251531y
[2016-01-05 06:05:30.040 UTC] Time Gain df-: 625 ms Percent: -36.53%
[2016-01-05 06:05:30.041 UTC]
[2016-01-05 06:05:30.041 UTC] Integer as Double by Dot:
[2016-01-05 06:05:31.794 UTC] TryParse (doubled) i+: 1752 ms Result: True Text: 1342517340
[2016-01-05 06:05:32.904 UTC] Extension (doubled) i+: 1109 ms Result: True Text: 1342517340
[2016-01-05 06:05:35.590 UTC] VB.IsNumeric (doubled) d+: 2684 ms Result: True Text: 1342517340
[2016-01-05 06:05:35.590 UTC] Time Gain d+: 643 ms Percent: -36.70%
[2016-01-05 06:05:35.591 UTC]
[2016-01-05 06:05:37.390 UTC] TryParse (doubled) i-: 1799 ms Result: True Text: -1342517340
[2016-01-05 06:05:38.515 UTC] Extension (doubled) i-: 1125 ms Result: True Text: -1342517340
[2016-01-05 06:05:41.139 UTC] VB.IsNumeric (doubled) d-: 2623 ms Result: True Text: -1342517340
[2016-01-05 06:05:41.139 UTC] Time Gain d-: 674 ms Percent: -37.47%
[2016-01-05 06:05:41.140 UTC]
[2016-01-05 06:05:42.840 UTC] TryParse (doubled) if+: 1700 ms Result: False Text: 134251734u
[2016-01-05 06:05:43.933 UTC] Extension (doubled) if+: 1092 ms Result: False Text: 134251734u
[2016-01-05 06:05:46.575 UTC] VB.IsNumeric (doubled) df+: 2642 ms Result: False Text: 134251734u
[2016-01-05 06:05:46.576 UTC] Time Gain df+: 608 ms Percent: -35.76%
[2016-01-05 06:05:46.577 UTC]
[2016-01-05 06:05:48.328 UTC] TryParse (doubled) if-: 1750 ms Result: False Text: -134251734u
[2016-01-05 06:05:49.434 UTC] Extension (doubled) if-: 1106 ms Result: False Text: -134251734u
[2016-01-05 06:05:52.042 UTC] VB.IsNumeric (doubled) df-: 2607 ms Result: False Text: -134251734u
[2016-01-05 06:05:52.042 UTC] Time Gain df-: 644 ms Percent: -36.80%
[2016-01-05 06:05:52.043 UTC]


到目前为止,我从结果中得出的结论是:


当文本类型是有效的正整数时,使用上述扩展方法可以获得的最佳性能提升。时间
在给定的条件下,我们可以获得的性能提升高达58.26%
案件。可能是由于有效的正整数文本的简单性。
当文本类型无效时,使用上述扩展方法可以获得的最糟糕的性能提升。时间
在给定的条件下,我们可以获得的性能提升仅为33.77%
案件。
对于整数和浮点/双精度(带/不带点)文本格式,要检查文本是否为那些格式而无需实际解析,可以通过构建我们自己的文本扩展名检查器来加快检查过程与使用内置 TryParse相比。在所有情况下,VB IsNumeric都比其余情况慢(这也令我感到惊讶,因为根据此 post中的基准测试,VB看起来非常快-尽管不是最好的)。




可能的用途:

此扩展名检查的一种可能用法是,当您收到某个字符串并且您知道它可以具有多种格式类型(例如,整数或双精度)时,但是您想先检查实际的文本类型而无需输入一个检查时的实际解析。对于这种给定的情况,扩展方法可以加快处理过程。

另一个用途是在计算语言领域,在此您经常想知道文本的类型,而无需实际解析该文本以供计算使用。

关于c# - 没有实际解析的TryParse或任何其他具有性能优势的文本格式检查选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34392763/

24 4 0
文章推荐: c# - 使用 OpenXML 打开 protected word 文档
文章推荐: javascript - React.js 中的初始化器?
文章推荐: javascript - 有条件地调用指令
文章推荐: javascript -
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com