2012-09-13 45 views
2

我試圖獲得使用C#.NET位的基本技能。我昨天發佈了一個例子,它帶有一個簡單的問題,需要進行位操作,這導致我有兩個主要方法 - 使用bitwise operators或使用.NET抽象,例如BitArray(請讓我知道是否有更多的內置工具可用於在.NET中使用除BitArray以外的位以及如何找到更多信息?)。按位運算符與C#中位操作的.NET抽象

據我所知,bitwise operators工作更快,但使用BitArray對我來說更容易一些,但我真正試圖避免的一件事是學習不好的做法。儘管我的個人偏好是針對.NET抽象的,但我想知道我真的能更好地學習和使用真正的程序。思考它我很想去想.NET抽象並沒有那麼糟糕,畢竟必須有理由在那裏,也許是一個初學者,學習抽象更自然,後來通過低級操作提高我的技能,但這只是隨意的想法。

+5

不知道我怎樣才能將這個短語作爲完整的答案,但是:在我能想到的幾乎每種常見的情況下,操作者方法都是優選的。我唯一需要看BitArray的是當我需要一個**任意大的**標記集時,a:非常罕見,而b:通過簡單的字節數組或int數組實現是微不足道的*無論如何* –

+1

@MarcGravell,好評...爲什麼仍然沒有那個神奇的「轉換評論回答」按鈕... –

+0

謝謝大家。很多有用的信息。 – Leron

回答

4

這真的取決於你在做什麼。當速度更受關注時,我會說使用按位操作,因爲它們的開銷要小得多。否則,BitArray應該沒問題。相關的主要開銷是函數調用和一些限制你可以做的「技巧」。

舉例來說,如果你想要做的東西,如果位0,3,或4,其中設置一個值:

if((value & 0b11001)>0) //not sure this is valid syntax, but you get the idea 
{ 
    //do stuff 
} 

這是因爲整型是本地CLR類型,轉換幾乎直接到只有3原生操作碼,movand,並cmp

這裏作爲一個BitArray,我看到的最effecient的方法是這樣的:

if(value[0] || value[3] || value[4]) 
{ 
    //... 
} 

在哪裏(假設不是JIT),這等於多達3個光復雜度函數調用。擺脫後盾整數位值的最簡單方式BitArray的(我認爲)是這樣的:

bool GetBit(int which) 
{ 
    return value & (1 << which)>0; 
} 

這基本上意味着它相當於是2倍左右慢只是一位對於這個超級簡單的情況下,這意味着我們正在檢查3位比較慢6倍。

而且對於BitArrays,副本可能更昂貴,因爲它們不是本機CLR類型。我懷疑這種開銷大部分會被拋出,但仍然需要考慮,特別是如果面向一個緊湊的框架。

基本上只使用BitArrays,如果你不需要對它們進行復雜的按位運算。

注意:您也可以使用混合方法在整數和BitArrays之間進行轉換,但這也會帶來相當大的開銷。

+0

'cmp'可以被刪除,因爲'and'設置標誌無論如何,然後''''可以通過將'和'更改爲'test'來刪除,這是無損的,所以這只是一條指令(理論上,無論如何,JIT編譯器是否足夠聰明?) – harold

+0

那麼,它依賴於@harold,這是一個完全的猜測,因爲它完全取決於JIT編譯器。通過IL的工作方式,它是一系列的push,並且比較,if-true等等,所以這主要是我的我確定有人真的專注於可以看到JIT編譯器本身編譯的結果 – Earlz

+0

好吧,我測試了它,並且JIT編譯器變得足夠聰明,只需生成'test'指令即可。至少我測試它的版本,這是版本4. – harold

3

我想知道我真的更好地學習和使用真正的程序。

兩人學習。他們並不那麼難以理解,你可以想象一個人會比另一個人更好的場景。

儘管我同意上面的@Marc Gravell,如果我需要處理大量的位(並且速度不是太大的問題),我只會考慮使用BitArray,但如果你最終在這種情況下,反正你可能做錯了什麼。在任何時候都在編程時

3

請記住這一點:

「是沒有問題的,可以不通過增加間接的另一層,來解決,除了具有間接的層次過多的問題」 。 - 大衛惠勒(對位)

通過使用BitArray,添加了一個間接層,其抽象出的位是如何管理和每個比特的值被產生和操縱的細節。這通常是一件好事,需要鼓勵;它會創建更清晰,更優雅,更易於閱讀的代碼。

但是,當你需要做一些複雜的事情時,會發生什麼?BitArray不允許你這樣做(或者做起來非常困難)?那時候,你的設計「過於抽象」。抽象層次妨礙你做你想做的事情,因爲他們太「愚蠢」了。這是一個信號重構抽象較少,在這種情況下,使用按位運算符需要更多的關心和理解,但基本上做任何事情可能做一組位。

因此,總之,使用BitArray解決您的問題,直到使用BitArray成爲它自己的問題。如果沒有BitArray,不要擔心你要做什麼;如果和有時是必要的,可以擔心。不要忘記如何使用按位運算符,或者它們存在。

+1

+1。特別是「不要忘記如何使用按位運算符,或者它們存在。」 :)我會在「使用BitArray解決您的問題」中稍微遠一些 - 不要使用位操作/ BitArray,除非您知道它正是您所需要的(即,您從某處獲取位標誌或者解決了「多少個1在這個值的二進制表示)在你的大部分代碼中,你永遠不會使用 - 常規的'bool isReady'屬性和字段顯着易於閱讀 –