![](/img/trans.png)
[英]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.