日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

C#由转换二进制所引起的思考,了解下?

發(fā)布時間:2023/12/4 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#由转换二进制所引起的思考,了解下? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
【導讀】最近遇到很有意思轉換二進制的問題,有部分童鞋儼然已了解,可能也有一部分童鞋沒碰到過也就不知情,這里我們來深入學習下轉換二進制所帶來的問題。

在寫此篇文章時,非常開心,收到再一次連任MVP的郵件,這是我第4年連任,希望能再接再厲,一如既往能夠給大家分享我所獲

二進制轉換問題

假設現(xiàn)在我們有一個int類型的數(shù)據(jù),它的范圍區(qū)間暫且定在0-15之間,我們需要將其轉換為二進制,然后獲取二進制中的每一位,若不足4位則0填充。看似很簡單是不是,直接通過C#內置APi即可達到此需求,如下:

?var?binary?=?Convert.ToString(7,?2).PadLeft(4,?'0').ToArray();

上述將數(shù)字7轉換為包含二進制位的字符串數(shù)組形式,7轉換二進制然后不足4位以0填充即(0111),我們如下獲取二進制位字符串數(shù)組為索引的位,結果應該打印出0,對嗎?

var?zerobit?=?binary[0]; Console.WriteLine(zerobit);

好像一點毛病也沒有,這是在控制臺中進行打印,若是將該數(shù)據(jù)導出到Excel中,你會發(fā)現(xiàn)結果將可能是48或49而不是0或1(你可以一試)這是因為如下:

我們通過調試可知實際上在字符0上還攜帶有48,這個48實際上是字符0的ASCII碼,字符1的ASCII碼是49,通過如下代碼即可證明:

foreach?(var?b?in?System.Text.Encoding.UTF8.GetBytes(binary)) {Console.WriteLine(b.ToString()); }


我們對將對應字符數(shù)組索引數(shù)據(jù)進行如下ToString轉換即可避免導出數(shù)據(jù)時可能出現(xiàn)的問題

var?zerobit?=?binary[0]; Console.WriteLine(zerobit.ToString());

轉換字符數(shù)組問題

當我們轉換為字符數(shù)組時,有兩種方式,既可采用上述ToArray方法,也可以通過ToCharArray方法來實現(xiàn),如下,那么哪種方法會更好呢?

var?binary?=?Convert.ToString(7,?2).PadLeft(4,?'0').ToArray();var?binary1?=?Convert.ToString(7,?2).PadLeft(4,?'0').ToCharArray();

此時比較此二者方法的性能好壞,只能去看對應源碼實現(xiàn),首先我們來看看ToCharArray方法,如下:

public?unsafe?char[]?ToCharArray() {if?(Length?==?0){return?Array.Empty<char>();}char[]?array?=?new?char[Length];fixed?(char*?smem?=?&_firstChar){fixed?(char*?dmem?=?&array[0]){wstrcpy(dmem,?smem,?Length);}}return?array; } internal?unsafe?static?void?wstrcpy(char*?dmem,?char*?smem,?int?charCount) {Buffer.Memmove((byte*)dmem,?(byte*)smem,?(uint)(charCount?*?2)); }

上述對于ToCharArray代碼量還是不多,我們來看看ToArray方法實現(xiàn),如下:

public?static?TSource[]?ToArray<TSource>(this?IEnumerable<TSource>?source) {if?(source?==?null){throw?Error.ArgumentNull("source");}return?new?Buffer<TSource>(source).ToArray(); }

上述只是寫了一個擴展方法,我們繼續(xù)往下看Buffer類的具體實現(xiàn),如下:

internal?Buffer(IEnumerable<TElement>?source) {TElement[]?array?=?null;int?num?=?0;ICollection<TElement>?collection?=?source?as?ICollection<TElement>;if?(collection?!=?null){num?=?collection.Count;if?(num?>?0){array?=?new?TElement[num];collection.CopyTo(array,?0);}}else{foreach?(TElement?item?in?source){if?(array?==?null){array?=?new?TElement[4];}else?if?(array.Length?==?num){TElement[]?array2?=?new?TElement[checked(num?*?2)];Array.Copy(array,?0,?array2,?0,?num);array?=?array2;}array[num]?=?item;num++;}}items?=?array;count?=?num; }

從代碼量上看就覺得ToArray方法實現(xiàn)稍微復雜一點,所以我們選擇使用ToCharArray會更好,我要是如此草草結束此文,一定會噴。

原歸正傳,我們一步步來分析,如上做了一點優(yōu)化,首先會判斷參數(shù)是否屬于集合接口,若是則直接通過復制轉換為數(shù)組形式,但是我們知道字符串肯定沒有實現(xiàn)ICollection<T>接口,所以走另外一個條件分支,但是有的童鞋可能就有疑問了,此時為何可以遍歷呢?那是因為針對字符實現(xiàn)了IEnumerable<char>接口,所以可以進行遍歷,如下

public?sealed?class?CharEnumerator?:?IEnumerator,?ICloneable,?IEnumerator<char>,?IDisposable {......}

接下來則是初始化容量為4的數(shù)組,為何這里為4呢?這里我認為應該談不上優(yōu)化,與其說是實現(xiàn)者的一種拍腦袋的想法,我傾向于理解為是一種權衡或考量,既然轉到此分支說明一定是轉換為二進制位的數(shù)組,比如上述進行填充后長度剛好為4。再接下來無用我再多講,就是遍歷所有字符數(shù)組,將每一個字符串添加到數(shù)組中去,直到數(shù)組長度和變量值(num)相等最終進行一次性復制,最終將數(shù)組賦值給數(shù)組元素以及將變量num賦值給數(shù)組元素的數(shù)量(count)。?

?

好了,講解了這么多,那么問題來了,到底誰的性能會更好呢?

ToCharArray方法實現(xiàn)底層采用指針操作轉化為字符數(shù)組,而利用ToArray方法由于string沒有實現(xiàn)ICollection<T>接口,也就是說根本不清楚字符串中字符數(shù)組的長度,所以只能采取低效遍歷的方式去進行轉換,我們可認為通過中間緩沖區(qū)的方式(即上述通過實例化數(shù)組作為橋梁最終進行復制)實現(xiàn)。

由此得出,在將字符串轉換為字符數(shù)組時,一定要用ToCharArray方法而不是ToArray,ToCharArray性能優(yōu)于ToArray方法,我不禁在想,針對字符轉換為數(shù)組只提供ToCharArray方法不就好了么,為何還要提供ToArray方法,讓人容易產生誤會,它的場景難道還有其他嗎?

本文詳細講解了在轉換二進制數(shù)據(jù)所引發(fā)的一點個人思考,在將字符串轉換為字符數(shù)組時,通過方法名稱意思可能直接就用ToCharArray方法,但是又偏偏提供了字符串的ToArray方法,其本質是針對字符數(shù)組的擴展方法,如果對源碼不了解的話,根本就不清楚到底應該用哪一個,從性能角度講,ToCharArray方法優(yōu)于ToArray方法,至于最終用哪一個,你說了算。

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結

以上是生活随笔為你收集整理的C#由转换二进制所引起的思考,了解下?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。