1、count和any
今天看了0 來判斷集合非空" href="" target="_blank">鶴沖天的文章:linq:切勿使用 count() > 0 來判斷集合非空 有所收穫,寫下文章總結一下:
先看如下**:
1static
void main(string
args)212
public
static ienumerable getnums(int start, int
count)
1318
public
static
void someaction(ienumerablesource)
1925 }
自己除錯了下,當yield迴圈低於100000次的話,count()和any()的執行時間差不多,count()時間略大於any()所耗費的時間,當大於100000次的話,count()執行時間就遠比any()執行時間多很多!例如上面的程式執行結果,count耗時2233毫秒,any卻只耗時3毫秒!這是為什麼呢?我們來看下原因:分別反編譯enumerate.count 的原始碼和enumerate.any的原始碼,如下:
enumerate.any 實現**如下:
1public
static
bool any(this ienumerablesource)27
using (ienumeratorenumerator =source.getenumerator())813
}14return
false
;15 }
enumerate.count 的原始碼如下:
1public
static
int count(this ienumerablesource)
27 icollectionis2 = source as icollection;
8if (is2 != null)9
12 icollection is3 = source as
icollection;
13if (is3 != null)14
17int num = 0;18
using (ienumeratorenumerator =source.getenumerator())
1924}25
return
num;
26 }
無論迴圈多少次,any方法執行的時間總是最少的,大概10毫秒之內,我想大家從any的原始碼可以知道這個原因,any方法先判斷集合是否為空,然後判斷集合是否有資料,只進行一次movenext(),並未進行迴圈查詢集合數量!所以耗費的時間當然一直是最少的了!
我們再看count方法,同樣是先進行集合判空操作,然後判斷當前的集合source是否能轉成icollection型別,如果能轉成,就直接返回此集合的count屬性,不會在進行下面的迴圈獲取集合個數的操作了,為什麼count()方法比any()方法執行的時間長呢?答案就在於此:因為getnums方法中用yield返回純粹的ienumerable型別,但是icollection是繼承自ienumerable型別的,所以必然不好被轉換,也就是count()原始碼中的下面**不會執行
icollection is3 = source asicollection;
if (is3 != null
)
上面的**不會執行,那麼必然會進行下面的**操作,也就是迴圈獲取集合的個數:
int num = 0;
using (ienumeratorenumerator =source.getenumerator())
}return num;
這樣必然會導致count()方法耗時很久!
2、如果我們把getnums進行如下修改,其他**不動:
publicstatic ienumerable getnums(int start, int
count)
這時我們在執行程式,可以看到無論迴圈次數多少,count和any兩者執行的時間差不多,大概是1315毫秒左右,其中1312毫秒用於list集合的裝填工作,3毫秒用於count或any的判斷時間,為什麼會出現這種情況呢,我想通過上面大家都知道了,因為此時getnums方法返回的是list型別,此型別繼承於icollection,所以必然可以被轉換,就會返回此型別的count屬性,count 方法對 icollection 進行了優化,直接訪返回它的 count 屬性,也就是返回乙個數,當然很快了,下面的迴圈獲取集合的個數當然也就不會執行了,也就節約了時間。
3、對某人問題的思考
有人說:」我有個程式裡經常要判集合裡是否僅有乙個元素,又不能用count,
不得已自己寫了個擴充套件方法 bool check(this ienumerablesource, int n), 當讀到第n+1個元素就直接返回false「
我想如果此人用的集合是繼承於icollection的話,例如list,那麼是沒必要對ienumerable進行擴充套件的,通過反編譯count原始碼可以知道,如果集合source可以轉換成icollection的話,是可以直接通過count屬性獲取到集合的總數量的,所以耗費的時間要不了多少,也就沒必要對ienumerable進行擴充套件了!反之,如果不是繼承icollection的話,例如ienumerable,就必須自己擴充套件ienumerable方法了,如果還用count的話,就會造成迴圈了,也就降低了程式的執行效率了!
4、參考
鶴沖天
2013-12-13 21:30:12
matlab 中all和any函式
all函式 檢 測矩陣中是否全為非零元素,如果是,則返回1,否則,返回0。any函式 檢測矩陣中是否有非零元素,如果有,則返回1,否則,返回0。用法和all一樣 語法 b all a b all a,dim 複製 b all a 如果a是乙個向量,如果所有的元素都是非零的,則返回1,如果有乙個元素為...
matlab中all和any用法
all函式 檢測矩陣中是否全為非零元素 any函式 檢測矩陣中是否有非零元素,如果有,則返回1,否則,返回0。用法和all一樣 語法 b all a b all a,dim 複製 b all a 如果a是乙個向量,如果所有的元素都是非零的,則返回1,如果有乙個元素為零,則返回0。如果a是乙個矩陣,則...
python中all 和any 函式總結
這個函式可能會有點坑,解釋如下 如果iterable的所有元素不為0,false或者iterable為空,函式all iterable 返回true,否則返回false。注意 空元組 空列表返回值為true。例項 all a b c d 列表list,元素都不為空或0 true all a b d ...