[英]How to count the number of true values in database where the column contains 'Q1'
[英]Using LINQ how do you filter a list of strings for values that match the pattern “q1, q2” etc.?
这应该是一个简单的方法,但我正在寻找最佳答案,至少要兼顾性能和优雅。
我有一个字符串列表, 某些值的格式为q1,q2,q3等。
我想选择这些。
这样做的最佳方法是什么?
最好的答案是使用Regex或Jay Bazuzi的int.TryParse建议 。
作为快速示例,请在LINQPad中尝试以下操作:
void Main()
{
int n = 100;
string[] a = {"q2", "q3", "b"};
a = a.Concat(Enumerable.Repeat(0,n).Select(i => "qasd")).ToArray(); /* Random data */
/* Regex Method */
System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex("^q[0-9]+$");
List<string> regMethod = a.Where(c => r.IsMatch(c)).ToList().Dump("Result");
/* IsInteger Method */
List<string> intMethod = a.Where(c => c.StartsWith("q") && IsInteger(c.Substring(1))).ToList().Dump("Result");
/* int.TryParse Method suggest by Jay Bazuzi */
int e = 0;
List<string> parseMethod = a.Where(c => c.StartsWith("q") && int.TryParse(c.Substring(1), out e)).ToList().Dump("Result");
}
public static bool IsInteger(string theValue)
{
try
{
Convert.ToInt32(theValue);
return true;
}
catch
{
return false;
}
}
尝试一次注释掉两种方法之一,并尝试不同n值的性能。
我的经验(在我的Core 2 Duo笔记本电脑上)似乎表明:
n = 100. Regex takes about 0.003 seconds, IsInteger takes about 0.01 seconds
n = 1,000. Regex takes about 0.004 seconds, IsInteger takes about 0.07 seconds
n = 10,000. Regex takes about 0.007 seconds, IsInteger takes about 0.67 seconds
n = 100,000. Regex takes about 0.046 seconds, IsInteger takes about 6.9 seconds
n = 1,000,000. Regex takes about 0.42 seconds, IsInteger takes about 1 minute and 6 seconds
ParseMethod具有与Regex相同的性能(如果以内联方式完成,与代码示例中的速度略快,如果以单独的方法(即,替换IsInteger方法主体)完成,则性能几乎相同)。
注意:创建字符串的成本未考虑在内(如果需要,可以插入日期差异),但是两种方法的成本相同
如果大多数键都不带有'q'(从不调用IsInteger),则这些数字更接近,但是即使在这种情况下 ,Regex也一样好或更好。
即(对于“ asdasd”而不是“ qasd”的填充字符串):
n = 100. Regex takes about 0.003 seconds, IsInteger takes about 0.003 seconds
n = 1,000. Regex takes about 0.004 seconds, IsInteger takes about 0.004 seconds
n = 10,000. Regex takes about 0.005 seconds, IsInteger takes about 0.005 seconds
n = 100,000. Regex takes about 0.023 seconds, IsInteger takes about 0.025 seconds
n = 1,000,000. Regex takes about 0.21 seconds, IsInteger takes about 0.22 seconds
同样,ParseMethod具有与Regex相同的性能。
结论:使用Regex或TryParse,在最坏的情况下它将更快,否则将更快
但是,是否有更好/更快捷的方法从字符串集合中选择int值? 也许以某种方式编译速度更快的通用过滤器?
似乎您正在尝试进行微优化,这意味着您将花费很多精力来使程序以相同的速度运行。 首先关注代码的清晰度,然后优化实际速度较慢的代码。
假设您已概要分析并发现这是您在实际场景中应用程序的瓶颈:
在非例外情况下使用例外情况很少(通常会降低性能)。 例如,请参见http://www.developerfusion.com/code/4650/validating-an-integer/ 。
根据情况的限制,最好将IsInteger()
更改为以下一项:
bool int.TryParse(string s, out int result);
(请参阅http://msdn.microsoft.com/zh-cn/library/system.int32.tryparse.aspx )
要么:
Microsoft.VisualBasic.Information.IsNumeric(object expression)
(请参阅http://www.hanselman.com/blog/ExploringIsNumericForC.aspx )
要么
x >= '0' && x < '9'
接着:
.Where(c => c[0] == 'q' && IsInteger(c[1]))
IsInteger的瓶颈可能是由于try-catch。
我尝试用TryParse替换IsInteger,并且得到以下结果(n = 1,000,000):
正则表达式方法:540 ms
TryParse方法:537毫秒
我将以下代码用于第二种方法:
Func<string, bool> lambda = (string c) => { Int32 temp;
return c.StartsWith("q")
&& int.TryParse(c.Substring(1),out temp); };
List<string> intMethod = a.Where(lambda).ToList();
这个故事的寓意是...
尽管我通常更喜欢使用Regex,但是在这种简单的字符串操作简单的情况下,TryParse解决方案是完全可以接受的。 在性能方面,使用哪种方法并不重要,但不要使用异常处理来检查某个字符串值是否为int!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.