成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

.net編碼和設(shè)計(jì)原則的示例分析-創(chuàng)新互聯(lián)

這篇文章主要為大家展示了“.net編碼和設(shè)計(jì)原則的示例分析”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“.net編碼和設(shè)計(jì)原則的示例分析”這篇文章吧。

公司主營業(yè)務(wù):成都網(wǎng)站制作、做網(wǎng)站、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)建站是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)建站推出尉犁免費(fèi)做網(wǎng)站回饋大家。類 vs 結(jié)構(gòu)體

類的實(shí)例都是在堆上分配的,通過指針的引用進(jìn)行訪問。傳遞這些對(duì)象代價(jià)很低,因?yàn)樗皇且粋€(gè)指針(4或者8直接)的拷貝。然而,對(duì)象也有一些固定開銷:8或16字節(jié)(32或64位系統(tǒng))。這些開銷包括指向方法表的指針和用于其它目的同步字段。但是,如果通過調(diào)試工具查看一個(gè)空對(duì)象占用的內(nèi)存,這會(huì)發(fā)現(xiàn)大了13或者24字節(jié)(32位或64位系統(tǒng))。這是.NET的內(nèi)存對(duì)齊機(jī)制導(dǎo)致的。

而結(jié)構(gòu)體則沒上面的開銷,它的內(nèi)存使用量就是字段大小的綜合。如果結(jié)構(gòu)體是方法(函數(shù))里聲明的局部變量,則它在堆棧上分配控件。如果結(jié)構(gòu)體被聲明為類的一部分,這結(jié)構(gòu)體使用的內(nèi)存這是該類的內(nèi)存布局里的一部分(因此它會(huì)分配在堆上)。但你將結(jié)構(gòu)體傳遞給方法(函數(shù))時(shí),他將對(duì)字節(jié)數(shù)據(jù)做復(fù)制。因?yàn)樗辉诙焉?,結(jié)構(gòu)體是不會(huì)導(dǎo)致垃圾回收的。

因此這里有一個(gè)折中。你可以找到各種關(guān)于結(jié)構(gòu)體尺寸大小的建議,但這里我不會(huì)告訴你一個(gè)確切的數(shù)字。在大多數(shù)情況下,你結(jié)構(gòu)體需要保持一個(gè)比較小的尺寸,特別是他們需要經(jīng)常被傳遞,你需要保證結(jié)構(gòu)體的大小不會(huì)造成太大的問題。唯一能確定的是,你需要根據(jù)自己的應(yīng)用場景進(jìn)行分析。

有些情況下,效率的差別還是蠻大的。當(dāng)一個(gè)對(duì)象開銷看起來不是很多,但是對(duì)比一個(gè)對(duì)象數(shù)組和結(jié)構(gòu)體數(shù)組就可以看出差別。在32位系統(tǒng)下,假設(shè)一個(gè)數(shù)據(jù)結(jié)構(gòu)包含16字節(jié)的數(shù)據(jù),數(shù)組長度是100w。
使用對(duì)象數(shù)組占用的空間
8字節(jié)數(shù)組開銷+
(4字節(jié)指針地址X1,000,000)+
((8字節(jié)頭部+16字節(jié)數(shù)據(jù))X1,000,000)
=28MB

使用結(jié)構(gòu)體數(shù)組占用的空間
8字節(jié)數(shù)組開銷+
(16字節(jié)數(shù)據(jù)X1,000,100)
=16MB

如果使用64位系統(tǒng),對(duì)象數(shù)組則使用40MB,而結(jié)構(gòu)體數(shù)組仍然是16MB。
可以看到,在一個(gè)結(jié)構(gòu)數(shù)組中,相同大小的數(shù)據(jù)占用的內(nèi)存小。隨著對(duì)象數(shù)組里對(duì)象的增加,還會(huì)增加GC的壓力。
除了空間,還有CPU效率問題。CPU有多級(jí)緩存。越靠近CPU的緩存越小,但訪問速度也會(huì)更快,對(duì)于順序保存的數(shù)據(jù)越容易優(yōu)化。
對(duì)于一個(gè)結(jié)構(gòu)體數(shù)組,他們?cè)趦?nèi)存里都是連續(xù)的值。訪問結(jié)構(gòu)體數(shù)組里數(shù)據(jù)很簡單,只要找到正確的位置就可以得到對(duì)應(yīng)的值。這就意味著在大數(shù)組數(shù)據(jù)做迭代訪問有巨大的差異。如果該值已經(jīng)在CPU的告訴緩存中,它的訪問速度是要比訪問RAM要快一個(gè)數(shù)量級(jí)。

如果要訪問對(duì)象數(shù)組里的某一項(xiàng),需要先獲得該對(duì)象的指針引用,再去堆里訪問。迭代對(duì)象數(shù)組的時(shí)候,就會(huì)造成數(shù)據(jù)指針在堆里跳轉(zhuǎn),頻繁更新CPU的緩存,進(jìn)而浪費(fèi)了很多訪問CPU緩存數(shù)據(jù)機(jī)會(huì)。

在很多時(shí)候,通過改進(jìn)數(shù)據(jù)保存在內(nèi)存的位置,降低CPU訪問內(nèi)存的開銷是使用結(jié)構(gòu)體的一個(gè)主要原因,它可以顯著的提升性能。

因?yàn)榻Y(jié)構(gòu)體使用的時(shí)候總是被復(fù)制,所以編碼時(shí)要很小心,否則你會(huì)產(chǎn)生一些有趣的bug。例如下面的栗子,你是無法通過編譯的:

struct Point
{
    public int x;
    public int y;
}

public static void Main()
{
    List<Point> points = new List<Point>();
    points.Add(new Point() {x = 1, y = 2});
    points[0].x = 3;
}

問題是在最后一行,你試圖修改列表里Point元素的某個(gè)值,這個(gè)操作是不行的,因?yàn)閜oints[0]返回的是原始值的一個(gè)副本。正確的修改值的方式是

Point p = points[0];
p.x = 3;
points[0] = p;

但是,你可以采取更嚴(yán)格的編碼策略:不要修改結(jié)構(gòu)體。一旦結(jié)構(gòu)體創(chuàng)建,永遠(yuǎn)不要改變他的值。這可以消除了上面的編譯問題,并簡化了結(jié)構(gòu)體的使用規(guī)則。
我之前提到,結(jié)構(gòu)體應(yīng)該保持小的體積,已避免花費(fèi)大量的時(shí)間來復(fù)制他們,但是偶爾也會(huì)使用一些大的結(jié)構(gòu)體。例如一個(gè)最終商業(yè)流程細(xì)節(jié)的對(duì)象,里面需要保存大量的時(shí)間戳:

class Order
{
    public DateTime ReceivedTime { get; set; }

    public DateTime AcknowledgeTime { get; set; }
    public DateTime ProcessBeginTime { get; set; }
    public DateTime WarehouseReceiveTime { get; set; }
    public DateTime WarehouseRunnerReceiveTime { get; set; }
    public DateTime WarehouseRunnerCompletionTime { get; set; }
    public DateTime PackingBeginTime { get; set; }
    public DateTime PackingEndTime { get; set; }
    public DateTime LabelPrintTime { get; set; }
    public DateTime CarrierNotifyTime { get; set; }
    public DateTime ProcessEndTime { get; set; }
    public DateTime EmailSentToCustomerTime { get; set; }
    public DateTime CarrerPickupTime { get; set; }
    // lots of other data ... 
}

為了簡化代碼,我們可以將時(shí)間的數(shù)據(jù)劃分到自己的子結(jié)構(gòu)里,這樣我們可以通過這樣的方式訪問Order對(duì)象:

Order order = new Order(); 
Order.Times.ReceivedTime = DateTime.UtcNow;

我們可以把數(shù)據(jù)全部放到自己的類里:

class OrderTimes
    {
        public DateTime ReceivedTime { get; set; }
        public DateTime AcknowledgeTime { get; set; }
        public DateTime ProcessBeginTime { get; set; }
        public DateTime WarehouseReceiveTime { get; set; }
        public DateTime WarehouseRunnerReceiveTime { get; set; }
        public DateTime WarehouseRunnerCompletionTime { get; set; }
        public DateTime PackingBeginTime { get; set; }
        public DateTime PackingEndTime { get; set; }
        public DateTime LabelPrintTime { get; set; }
        public DateTime CarrierNotifyTime { get; set; }
        public DateTime ProcessEndTime { get; set; }
        public DateTime EmailSentToCustomerTime { get; set; }
        public DateTime CarrerPickupTime { get; set; }
    }

    class Order
    {
        public OrderTimes Times;
    }

但是,這樣會(huì)為每個(gè)Order對(duì)象引入額外的12或者24字節(jié)的開銷。如果你需要將OrderTimes對(duì)象作為一個(gè)整體傳入各種方法函數(shù)里,這也許是有一定道理的,但為什么不把Order對(duì)象傳入方法里呢?如果你同時(shí)有數(shù)千個(gè)Order對(duì)象,則可能會(huì)導(dǎo)致更多的垃圾回收,這是額外的對(duì)象增加的引用導(dǎo)致的。
相反,將OrderTime更改為結(jié)構(gòu)體,通過Order上的屬性(例如:Order.Times.ReceivedTime)訪問OrderTImes結(jié)構(gòu)體的各個(gè)屬性,不會(huì)導(dǎo)致結(jié)構(gòu)體的副本(.NET會(huì)對(duì)這個(gè)訪問做優(yōu)化)。這樣OrderTimes結(jié)構(gòu)體基本上成為Order類的內(nèi)存布局的一部分,幾乎和沒有子結(jié)構(gòu)體一樣了,你擁有了更加漂亮的代碼。
這種技術(shù)確實(shí)違反了不可變的結(jié)構(gòu)體原理,但這里的技巧就是將OrderTimes結(jié)構(gòu)的字段視為Order對(duì)象的字段。你不需要將OrderTimes結(jié)構(gòu)體作為一個(gè)實(shí)體進(jìn)行傳遞,它只是一個(gè)代碼組織方式。

以上是“.net編碼和設(shè)計(jì)原則的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

網(wǎng)頁題目:.net編碼和設(shè)計(jì)原則的示例分析-創(chuàng)新互聯(lián)
網(wǎng)站URL:http://jinyejixie.com/article2/dieioc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計(jì)定制網(wǎng)站、網(wǎng)站策劃關(guān)鍵詞優(yōu)化、自適應(yīng)網(wǎng)站網(wǎng)站收錄

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)
广元市| 三原县| 柘城县| 荣昌县| 绥中县| 肃南| 永新县| 濉溪县| 新营市| 溧水县| 安化县| 邯郸县| 孝义市| 木兰县| 莱西市| 全南县| 汤阴县| 行唐县| 武乡县| 佛坪县| 云南省| 石泉县| 仁怀市| 十堰市| 抚松县| 石河子市| 济宁市| 南城县| 镇原县| 濉溪县| 岐山县| 滕州市| 龙陵县| 神池县| 龙海市| 宜章县| 蓝田县| 滦平县| 右玉县| 民丰县| 土默特左旗|