本發(fā)明涉及計(jì)算機(jī)技術(shù)領(lǐng)域,尤其涉及一種對(duì)象序列化方法、裝置和計(jì)算設(shè)備。
背景技術(shù):
序列化(Serialization)是一種將對(duì)象的狀態(tài)信息轉(zhuǎn)換為可以存儲(chǔ)或傳輸?shù)男问降倪^(guò)程。在該過(guò)程中,首先將序列化的結(jié)果寫(xiě)入緩沖區(qū),再將緩沖區(qū)中的內(nèi)容輸出或?qū)懭氪疟P(pán)?;谀壳暗膽?yīng)用場(chǎng)景,序列化的轉(zhuǎn)換形式主要包括Json、Xml、Binary等。在云計(jì)算及高性能計(jì)算領(lǐng)域,序列化的性能通常會(huì)對(duì)系統(tǒng)的計(jì)算性能造成很大的影響。
現(xiàn)有的序列化方案多采用系統(tǒng)的原始API,而在系統(tǒng)的序列化API中,數(shù)據(jù)無(wú)法直接寫(xiě)入到緩沖區(qū),而是要先在緩沖區(qū)之外再分配一個(gè)小容量的臨時(shí)緩沖區(qū),在該臨時(shí)緩沖區(qū)中將數(shù)據(jù)轉(zhuǎn)換成一個(gè)新的字符串對(duì)象,然后再將該字符串對(duì)象從臨時(shí)緩沖區(qū)拷貝至緩沖區(qū)(如圖1所示)。該方法會(huì)頻繁地生成新對(duì)象,并在使用完畢后立即銷(xiāo)毀,加重了垃圾回收(GC,Garbage Collection)的負(fù)擔(dān),降低了系統(tǒng)性能。
現(xiàn)有的序列化方法中,往往采用多次分配擴(kuò)容的內(nèi)存分配方式,即,首先為序列化分配一塊內(nèi)存作為序列化的緩沖區(qū),在執(zhí)行序列化的過(guò)程中,當(dāng)緩沖區(qū)空間不夠時(shí),重新申請(qǐng)一塊更大的內(nèi)存作為新的緩沖區(qū),將之前已寫(xiě)入舊緩沖區(qū)的數(shù)據(jù)拷貝到新緩沖區(qū)中,然后釋放舊緩沖區(qū)中的數(shù)據(jù),由系統(tǒng)對(duì)舊的緩沖區(qū)進(jìn)行垃圾回收。該方法需要多次申請(qǐng)內(nèi)存,增加了系統(tǒng)進(jìn)行垃圾回收的負(fù)擔(dān)。由于申請(qǐng)內(nèi)存時(shí)需要連續(xù)的空間,該方法也增加了系統(tǒng)進(jìn)行內(nèi)存整理的頻率。此外,該方法需要頻繁地進(jìn)行緩沖區(qū)邊界檢查、數(shù)據(jù)拷貝和遷移,消耗了大量的CPU資源。
在進(jìn)行序列化時(shí),針對(duì)不同的數(shù)據(jù)類(lèi)型,需要不同的序列化方法?,F(xiàn)有的序列化方法多采用多條件分支判斷來(lái)實(shí)現(xiàn)不同類(lèi)型數(shù)據(jù)的序列化:首先采用反射機(jī)制獲取對(duì)象(Object)中某個(gè)屬性的屬性值,采用反射機(jī)制獲取的屬性值仍是一個(gè)對(duì)象。隨后,需要采用GetType()來(lái)獲取該屬性值的數(shù)據(jù)類(lèi)型,接下來(lái)對(duì)該屬性值的數(shù)據(jù)類(lèi)型進(jìn)行多條件分支判斷,從而采用合適的序列化方法來(lái)對(duì)該屬性值進(jìn)行序列化(如圖2所示)。該方法中,反射機(jī)制需要消耗較多的系統(tǒng)資源和處理時(shí)間,通過(guò)反射機(jī)制來(lái)獲取屬性值的數(shù)據(jù)類(lèi)型效率較低。此外,在面向?qū)ο蟮恼Z(yǔ)言中數(shù)據(jù)類(lèi)型可知的情況下,該方法中的多條件分支相當(dāng)于做了大量的無(wú)效判斷,大大降低了序列化的處理性能。
技術(shù)實(shí)現(xiàn)要素:
為此,本發(fā)明提供一種對(duì)象序列化方法、裝置和計(jì)算設(shè)備,以力圖解決或至少緩解上面存在的問(wèn)題。
根據(jù)本發(fā)明的一個(gè)方面,提供一種對(duì)象序列化方法,在計(jì)算設(shè)備中執(zhí)行,所述對(duì)象具有一個(gè)或多個(gè)屬性,所述方法包括:依次獲取對(duì)象中各屬性的屬性信息,所述屬性信息包括數(shù)據(jù)類(lèi)型、屬性名和屬性值;根據(jù)各屬性的屬性信息來(lái)確定整體緩沖區(qū)的預(yù)估容量,所述整體緩沖區(qū)適于緩存所述對(duì)象序列化的結(jié)果;向操作系統(tǒng)請(qǐng)求具有所述預(yù)估容量的整體緩沖區(qū);依次根據(jù)各屬性的數(shù)據(jù)類(lèi)型對(duì)各屬性進(jìn)行序列化,將序列化后的結(jié)果寫(xiě)入整體緩沖區(qū)。
可選地,在根據(jù)本發(fā)明的對(duì)象序列化方法中,根據(jù)各屬性的屬性信息來(lái)確定整體緩沖區(qū)的預(yù)估容量的步驟包括:確定所述對(duì)象的所有屬性名所占用的總字節(jié)數(shù);預(yù)估所述對(duì)象的所有屬性值的序列化結(jié)果所占用的總字節(jié)數(shù);確定對(duì)象序列化結(jié)果中分隔符、標(biāo)識(shí)符所占用的總字節(jié)數(shù);將上述總字節(jié)數(shù)之和作為整體緩沖區(qū)的預(yù)估容量。
可選地,在根據(jù)本發(fā)明的對(duì)象序列化方法中,按照以下步驟預(yù)估所述對(duì)象的各屬性值的序列化結(jié)果所占用的字節(jié)數(shù):對(duì)于所占用的存儲(chǔ)空間固定的數(shù)據(jù)類(lèi)型,將該數(shù)據(jù)類(lèi)型的數(shù)據(jù)的序列化結(jié)果所能占用的最大字節(jié)數(shù)作為具有該數(shù)據(jù)類(lèi)型的屬性值的序列化結(jié)果所占用的字節(jié)數(shù);對(duì)于所占用的存儲(chǔ)空間不固定但是能夠獲取屬性值長(zhǎng)度的數(shù)據(jù)類(lèi)型,獲取該屬性值的長(zhǎng)度,根據(jù)所述長(zhǎng)度來(lái)確定該屬性值的序列化結(jié)果所占用的字節(jié)數(shù)。
可選地,在根據(jù)本發(fā)明的對(duì)象序列化方法中,依次根據(jù)各屬性的數(shù)據(jù)類(lèi)型對(duì)各屬性進(jìn)行序列化,將序列化后的結(jié)果寫(xiě)入整體緩沖區(qū)的步驟包括:對(duì)于每個(gè)屬性,將標(biāo)識(shí)符、屬性名、分隔符寫(xiě)入整體緩沖區(qū);根據(jù)該屬性的數(shù)據(jù)類(lèi)型對(duì)屬性值進(jìn)行序列化,將序列化結(jié)果寫(xiě)入整體緩沖區(qū)。
可選地,在根據(jù)本發(fā)明的對(duì)象序列化方法中,根據(jù)該屬性的數(shù)據(jù)類(lèi)型對(duì)屬性值進(jìn)行序列化的步驟包括:通過(guò)動(dòng)態(tài)編譯獲取該屬性的數(shù)據(jù)類(lèi)型,根據(jù)所獲取的數(shù)據(jù)類(lèi)型調(diào)用相應(yīng)的序列化方法對(duì)該屬性值進(jìn)行序列化。
可選地,在根據(jù)本發(fā)明的對(duì)象序列化方法中,當(dāng)數(shù)據(jù)類(lèi)型為整數(shù)類(lèi)型時(shí),所述根據(jù)該屬性的數(shù)據(jù)類(lèi)型對(duì)屬性值進(jìn)行序列化,將序列化結(jié)果寫(xiě)入整體緩沖區(qū)的步驟包括:若屬性值小于預(yù)設(shè)的閾值,則按照從高位到低位的順序依次序列化所述屬性值的每一位數(shù)據(jù),將每一位數(shù)據(jù)的序列化結(jié)果依次寫(xiě)入整體緩沖區(qū)的固定區(qū)域,所述固定區(qū)域?yàn)閺姆指舴蟮谝粋€(gè)字節(jié)開(kāi)始的、長(zhǎng)度為該類(lèi)型數(shù)據(jù)的序列化結(jié)果所能占用的最大字節(jié)數(shù)的區(qū)域,其中,將屬性值的最高位數(shù)據(jù)的序列化結(jié)果寫(xiě)入固定區(qū)域的第一位,將屬性值的次高位數(shù)據(jù)的序列化結(jié)果寫(xiě)入固定區(qū)域的第二位,以此類(lèi)推;若屬性值大于等于所述閾值,則按照從低位到高位的順序依次序列化所述屬性值的每一位數(shù)據(jù),將每一位數(shù)據(jù)的序列化結(jié)果依次寫(xiě)入整體緩沖區(qū)的固定區(qū)域,其中,將屬性值的最低位數(shù)據(jù)的序列化結(jié)果寫(xiě)入固定區(qū)域的最后一位,將屬性值的次低位數(shù)據(jù)的序列化結(jié)果寫(xiě)入固定區(qū)域的倒數(shù)第二位,以此類(lèi)推;在屬性值的序列化結(jié)果全部寫(xiě)入固定區(qū)域后,將屬性值的序列化結(jié)果移至固定區(qū)域的最前端。
可選地,在根據(jù)本發(fā)明的對(duì)象序列化方法中,采用指針來(lái)執(zhí)行所述寫(xiě)入的步驟。
可選地,在根據(jù)本發(fā)明的對(duì)象序列化方法中,在完成對(duì)象序列化之后,對(duì)所述整體緩沖區(qū)進(jìn)行回收以實(shí)現(xiàn)緩沖區(qū)重用。
可選地,在根據(jù)本發(fā)明的對(duì)象序列化方法中,在所述向操作系統(tǒng)請(qǐng)求具有所述預(yù)估容量的整體緩沖區(qū)的步驟之前,還包括:判斷現(xiàn)有的緩沖區(qū)中是否存在容量大于等于所述預(yù)估容量的緩沖區(qū);若是,則將該容量大于等于所述預(yù)估容量的緩沖區(qū)作為本次對(duì)象序列化的整體緩沖區(qū);若否,則向操作系統(tǒng)請(qǐng)求具有所述預(yù)估容量的整體緩沖區(qū)。
根據(jù)本發(fā)明的一個(gè)方面,提供一種對(duì)象序列化裝置,駐留于計(jì)算設(shè)備中,其中,所述對(duì)象具有一個(gè)或多個(gè)屬性,所述裝置包括:信息獲取模塊,適于依次獲取對(duì)象中各屬性的屬性信息,所述屬性信息包括數(shù)據(jù)類(lèi)型、屬性名和屬性值;容量預(yù)估模塊,適于根據(jù)各屬性的屬性信息來(lái)確定整體緩沖區(qū)的預(yù)估容量,所述整體緩沖區(qū)適于緩存所述對(duì)象序列化的結(jié)果;緩沖區(qū)請(qǐng)求模塊,適于向操作系統(tǒng)請(qǐng)求具有所述預(yù)估容量的整體緩沖區(qū);序列化模塊,適于依次根據(jù)各屬性的類(lèi)型對(duì)各屬性進(jìn)行序列化,將序列化后的結(jié)果寫(xiě)入整體緩沖區(qū)。
根據(jù)本發(fā)明的一個(gè)方面,提供一種計(jì)算設(shè)備,包括如上所述的對(duì)象序列化裝置。
根據(jù)本發(fā)明的技術(shù)方案,根據(jù)對(duì)象中各屬性的屬性信息來(lái)預(yù)估整體緩沖區(qū)的容量,一次性申請(qǐng)內(nèi)存,避免了多次生成新對(duì)象并拋棄以及對(duì)緩沖區(qū)進(jìn)行多次擴(kuò)容所造成的性能消耗。同時(shí),這種整體緩沖區(qū)的分配方法能夠保證數(shù)據(jù)的寫(xiě)入不會(huì)越界,因此可以直接采用指針來(lái)寫(xiě)入數(shù)據(jù),避免語(yǔ)言框架的邊界檢查所造成的性能消耗。
本發(fā)明在對(duì)對(duì)象進(jìn)行序列化時(shí),采用動(dòng)態(tài)編譯框架,能夠獲取屬性的數(shù)據(jù)類(lèi)型,并根據(jù)數(shù)據(jù)類(lèi)型調(diào)用相應(yīng)的序列化方法來(lái)對(duì)該屬性進(jìn)行序列化。該對(duì)象序列化方法是一個(gè)順序執(zhí)行的過(guò)程,無(wú)需采用反射機(jī)制,也無(wú)需進(jìn)行多條件分支判斷,節(jié)省了系統(tǒng)資源,提高了序列化效率。
在本發(fā)明中,針對(duì)各數(shù)據(jù)類(lèi)型的特點(diǎn),預(yù)先生成了對(duì)不同數(shù)據(jù)類(lèi)型進(jìn)行序列化的方法,以提高序列化性能。例如,對(duì)于整數(shù)類(lèi)型(byte、int、short、long等)的屬性,當(dāng)屬性值較小時(shí),直接按照從高位到低位的順序依次序列化該屬性值的每一位數(shù)據(jù)并依次寫(xiě)入整體緩沖區(qū),避免了整體緩沖區(qū)中的數(shù)據(jù)移動(dòng),提高了序列化效率。
此外,本發(fā)明在完成對(duì)象序列化后,對(duì)整體緩沖區(qū)進(jìn)行回收,統(tǒng)一管理。在為下一次對(duì)象序列化分配整體緩沖區(qū)時(shí),優(yōu)先使用已有的緩沖區(qū)進(jìn)行分配,無(wú)需向操作系統(tǒng)重新申請(qǐng)內(nèi)存,減少了CPU的負(fù)擔(dān)。對(duì)于預(yù)估容量較大的整體緩沖區(qū)分配,該方案的性能優(yōu)勢(shì)體現(xiàn)得更為明顯。
附圖說(shuō)明
為了實(shí)現(xiàn)上述以及相關(guān)目的,本文結(jié)合下面的描述和附圖來(lái)描述某些說(shuō)明性方面,這些方面指示了可以實(shí)踐本文所公開(kāi)的原理的各種方式,并且所有方面及其等效方面旨在落入所要求保護(hù)的主題的范圍內(nèi)。通過(guò)結(jié)合附圖閱讀下面的詳細(xì)描述,本公開(kāi)的上述以及其它目的、特征和優(yōu)勢(shì)將變得更加明顯。遍及本公開(kāi),相同的附圖標(biāo)記通常指代相同的部件或元素。
圖1示出了現(xiàn)有技術(shù)中的一種不斷生成新對(duì)象的序列化方法的示意圖;
圖2示出了現(xiàn)有技術(shù)中的一種多條件分支判斷的序列化方法的示意圖;
圖3示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的計(jì)算設(shè)備300的結(jié)構(gòu)圖;
圖4示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的對(duì)象序列化裝置400的結(jié)構(gòu)圖;
圖5A-5C示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的屬性值序列化過(guò)程的示意圖;
圖6A-6B示出了根據(jù)本發(fā)明另一個(gè)實(shí)施例的屬性值序列化過(guò)程的示意圖;
圖7示出了根據(jù)本發(fā)明另一個(gè)實(shí)施例的對(duì)象序列化裝置700的結(jié)構(gòu)圖;
圖8示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的對(duì)象序列化方法800的流程圖;
圖9示出了根據(jù)本發(fā)明另一個(gè)實(shí)施例的對(duì)象序列化方法900的流程圖;以及
圖10示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的對(duì)一個(gè)Student對(duì)象進(jìn)行序列化的示意圖。
具體實(shí)施方式
下面將參照附圖更詳細(xì)地描述本公開(kāi)的示例性實(shí)施例。雖然附圖中顯示了本公開(kāi)的示例性實(shí)施例,然而應(yīng)當(dāng)理解,可以以各種形式實(shí)現(xiàn)本公開(kāi)而不應(yīng)被這里闡述的實(shí)施例所限制。相反,提供這些實(shí)施例是為了能夠更透徹地理解本公開(kāi),并且能夠?qū)⒈竟_(kāi)的范圍完整的傳達(dá)給本領(lǐng)域的技術(shù)人員。
圖3示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的計(jì)算設(shè)備300的結(jié)構(gòu)圖。在基本配置302中,計(jì)算設(shè)備300典型地包括系統(tǒng)存儲(chǔ)器306和一個(gè)或者多個(gè)處理器304。存儲(chǔ)器總線(xiàn)308可以用于在處理器304和系統(tǒng)存儲(chǔ)器306之間的通信。
取決于期望的配置,處理器304可以是任何類(lèi)型的處理,包括但不限于:微處理器(μP)、微控制器(μC)、數(shù)字信息處理器(DSP)或者它們的任何組合。處理器304可以包括諸如一級(jí)高速緩存310和二級(jí)高速緩存312之類(lèi)的一個(gè)或者多個(gè)級(jí)別的高速緩存、處理器核心314和寄存器316。示例的處理器核心314可以包括運(yùn)算邏輯單元(ALU)、浮點(diǎn)數(shù)單元(FPU)、數(shù)字信號(hào)處理核心(DSP核心)或者它們的任何組合。示例的存儲(chǔ)器控制器318可以與處理器304一起使用,或者在一些實(shí)現(xiàn)中,存儲(chǔ)器控制器318可以是處理器304的一個(gè)內(nèi)部部分。
取決于期望的配置,系統(tǒng)存儲(chǔ)器306可以是任意類(lèi)型的存儲(chǔ)器,包括但不限于:易失性存儲(chǔ)器(諸如RAM)、非易失性存儲(chǔ)器(諸如ROM、閃存等)或者它們的任何組合。系統(tǒng)存儲(chǔ)器306可以包括操作系統(tǒng)320、一個(gè)或者多個(gè)應(yīng)用322以及程序數(shù)據(jù)324。在一些實(shí)施方式中,應(yīng)用322可以布置為在操作系統(tǒng)上利用程序數(shù)據(jù)324進(jìn)行操作。
計(jì)算設(shè)備300還可以包括有助于從各種接口設(shè)備(例如,輸出設(shè)備342、外設(shè)接口344和通信設(shè)備346)到基本配置302經(jīng)由總線(xiàn)/接口控制器330的通信的接口總線(xiàn)340。示例的輸出設(shè)備342包括圖形處理單元348和音頻處理單元350。它們可以被配置為有助于經(jīng)由一個(gè)或者多個(gè)A/V端口352與諸如顯示器或者揚(yáng)聲器之類(lèi)的各種外部設(shè)備進(jìn)行通信。示例外設(shè)接口344可以包括串行接口控制器354和并行接口控制器356,它們可以被配置為有助于經(jīng)由一個(gè)或者多個(gè)I/O端口358和諸如輸入設(shè)備(例如,鍵盤(pán)、鼠標(biāo)、筆、語(yǔ)音輸入設(shè)備、觸摸輸入設(shè)備)或者其他外設(shè)(例如打印機(jī)、掃描儀等)之類(lèi)的外部設(shè)備進(jìn)行通信。示例的通信設(shè)備346可以包括網(wǎng)絡(luò)控制器360,其可以被布置為便于經(jīng)由一個(gè)或者多個(gè)通信端口364與一個(gè)或者多個(gè)其他計(jì)算設(shè)備362通過(guò)網(wǎng)絡(luò)通信鏈路的通信。
網(wǎng)絡(luò)通信鏈路可以是通信介質(zhì)的一個(gè)示例。通信介質(zhì)通??梢泽w現(xiàn)為在諸如載波或者其他傳輸機(jī)制之類(lèi)的調(diào)制數(shù)據(jù)信號(hào)中的計(jì)算機(jī)可讀指令、數(shù)據(jù)結(jié)構(gòu)、程序模塊,并且可以包括任何信息遞送介質(zhì)。“調(diào)制數(shù)據(jù)信號(hào)”可以這樣的信號(hào),它的數(shù)據(jù)集中的一個(gè)或者多個(gè)或者它的改變可以在信號(hào)中編碼信息的方式進(jìn)行。作為非限制性的示例,通信介質(zhì)可以包括諸如有線(xiàn)網(wǎng)絡(luò)或者專(zhuān)線(xiàn)網(wǎng)絡(luò)之類(lèi)的有線(xiàn)介質(zhì),以及諸如聲音、射頻(RF)、微波、紅外(IR)或者其它無(wú)線(xiàn)介質(zhì)在內(nèi)的各種無(wú)線(xiàn)介質(zhì)。這里使用的術(shù)語(yǔ)計(jì)算機(jī)可讀介質(zhì)可以包括存儲(chǔ)介質(zhì)和通信介質(zhì)二者。
計(jì)算設(shè)備300可以實(shí)現(xiàn)為服務(wù)器,例如文件服務(wù)器、數(shù)據(jù)庫(kù)服務(wù)器、應(yīng)用程序服務(wù)器和WEB服務(wù)器等,也可以實(shí)現(xiàn)為包括桌面計(jì)算機(jī)和筆記本計(jì)算機(jī)配置的個(gè)人計(jì)算機(jī)。此外,計(jì)算設(shè)備300還可以實(shí)現(xiàn)為小尺寸便攜(或者移動(dòng))電子設(shè)備的一部分,這些電子設(shè)備可以是諸如蜂窩電話(huà)、個(gè)人數(shù)字助理(PDA)、個(gè)人媒體播放器設(shè)備、無(wú)線(xiàn)網(wǎng)絡(luò)瀏覽設(shè)備、個(gè)人頭戴設(shè)備、應(yīng)用專(zhuān)用設(shè)備、或者可以包括上面任何功能的混合設(shè)備。待測(cè)設(shè)備可以是桌面電腦、筆記本電腦、平板電腦、手機(jī)等具有運(yùn)算能力的設(shè)備。
本發(fā)明中,計(jì)算設(shè)備300的應(yīng)用322中包括對(duì)象序列化裝置400,使得計(jì)算設(shè)備300能夠?qū)崿F(xiàn)高效的序列化。對(duì)象序列化裝置400可以作為一個(gè)插件駐留于計(jì)算設(shè)備300的瀏覽器中,或作為一個(gè)獨(dú)立的軟件安裝于計(jì)算設(shè)備300中,或作為駐留于計(jì)算設(shè)備300中的某個(gè)軟件的一部分來(lái)實(shí)現(xiàn)對(duì)象序列化的功能,本發(fā)明對(duì)對(duì)象序列化裝置400在計(jì)算設(shè)備300中的存在形式不做限制。
圖4示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的對(duì)象序列化裝置400的結(jié)構(gòu)圖。如圖4所示,對(duì)象序列化裝置400包括信息獲取模塊410、容量預(yù)估模塊420、緩存區(qū)請(qǐng)求模塊430和序列化模塊440。
信息獲取模塊410適于依次獲取對(duì)象中各屬性的屬性信息,其中,“依次”指的是按照屬性在對(duì)象中出現(xiàn)的順序依次獲取對(duì)象中的屬性信息,即首先獲取對(duì)象中出現(xiàn)的第一個(gè)屬性的屬性信息,再獲取對(duì)象中出現(xiàn)的第二個(gè)屬性的屬性信息,以此類(lèi)推。屬性信息包括數(shù)據(jù)類(lèi)型、屬性名和屬性值。例如,對(duì)象中有一個(gè)屬性int age=18,對(duì)于該屬性,其數(shù)據(jù)類(lèi)型為int,屬性名為age,屬性值為18。
信息獲取模塊410獲取了對(duì)象中各屬性的屬性信息后,容量預(yù)估模塊420根據(jù)各屬性的屬性信息來(lái)確定整體緩沖區(qū)的預(yù)估容量。整體緩沖區(qū)用于緩存該對(duì)象序列化的結(jié)果,在對(duì)象序列化完成后,可以根據(jù)需要將整體緩沖區(qū)中的內(nèi)容輸出或存入磁盤(pán)。
JSON是比較常用的序列化目標(biāo)格式。JSON格式的對(duì)象序列化結(jié)果是一個(gè)由對(duì)象中各屬性的“屬性名-屬性值”對(duì)所構(gòu)成的字符串集合。該字符串集合以左大括號(hào)({)開(kāi)始,以右大括號(hào)(})結(jié)束,屬性名和字符類(lèi)型的屬性值均需要用雙引號(hào)(“”)括起來(lái),數(shù)組類(lèi)型的屬性值需要用中括號(hào)([)括起來(lái),JSON類(lèi)型的屬性值需要用大括號(hào)({})括起來(lái)。屬性名和屬性值之間使用冒號(hào)(:)分隔,各“屬性名-屬性值”對(duì)之間使用逗號(hào)(,)分隔。
根據(jù)一種實(shí)施例,JSON格式的序列化結(jié)果可以分為以下三部分:
1)各屬性名的序列化結(jié)果。
2)各屬性值的序列化結(jié)果。
3)分隔符、標(biāo)識(shí)符。分隔符為屬性值和屬性值之間的冒號(hào)(:)和各“屬性名-屬性值”對(duì)之間的逗號(hào)(,),標(biāo)識(shí)符為用于表示屬性名和字符類(lèi)型的屬性值的雙引號(hào)(“”)、用于表示數(shù)組類(lèi)型的屬性值的中括號(hào)([])和用于表示JSON類(lèi)型的屬性值的大括號(hào)({})。
例如,屬性int age=18的序列化結(jié)果為{“Age”:18},該序列化結(jié)果包括屬性名Age,屬性值的序列化結(jié)果18,分隔符冒號(hào)(:),標(biāo)識(shí)符大括號(hào)({})和標(biāo)識(shí)符雙引號(hào)(“”)。
JSON格式的序列化結(jié)果包括以上三部分,其中,對(duì)于一個(gè)確定的對(duì)象,其包括的屬性名也是確定的,且屬性名均為字符串,在進(jìn)行屬性名的序列化時(shí),直接將屬性名拷貝至整體緩沖區(qū)中即可,整體緩沖區(qū)中各屬性名所占用的總字節(jié)數(shù)即為各屬性名中所包含的字符數(shù)的總和。序列化結(jié)果中分隔符的總數(shù)目也是固定的,對(duì)于一個(gè)不包含復(fù)雜數(shù)據(jù)類(lèi)型(數(shù)組、JSON、Dictionary等)的對(duì)象,其分隔符數(shù)目為(2*屬性個(gè)數(shù)-1),即分隔符所占用的總字節(jié)數(shù)為(2*屬性個(gè)數(shù)-1);對(duì)于一個(gè)包含復(fù)雜數(shù)據(jù)類(lèi)型的對(duì)象,其分隔符的數(shù)目也可以根據(jù)數(shù)據(jù)類(lèi)型的具體情況計(jì)算出來(lái)。序列化結(jié)果中標(biāo)識(shí)符的數(shù)目也是固定的,對(duì)于一個(gè)不包含復(fù)雜數(shù)據(jù)類(lèi)型的對(duì)象,其標(biāo)識(shí)符數(shù)目為(屬性個(gè)數(shù)*2+非數(shù)值類(lèi)型的屬性個(gè)數(shù)*2+2),相應(yīng)地,標(biāo)識(shí)符所占用的總字節(jié)數(shù)為(屬性個(gè)數(shù)*2+非數(shù)值類(lèi)型的屬性個(gè)數(shù)*2+2);對(duì)于一個(gè)包含復(fù)雜數(shù)據(jù)類(lèi)型的對(duì)象,其標(biāo)識(shí)符的數(shù)目也可以根據(jù)數(shù)據(jù)類(lèi)型的具體情況計(jì)算出來(lái)。而各屬性的屬性值的序列化結(jié)果所占用的字節(jié)數(shù)在未進(jìn)行序列化時(shí)很難確定。
因此,為了確定整體緩沖區(qū)的預(yù)估容量,容量預(yù)估模塊420需要確定各屬性名所占用的總字節(jié)數(shù),分隔符、標(biāo)識(shí)符所占用的總字節(jié)數(shù),以及預(yù)估各屬性值的序列化結(jié)果所占用的總字節(jié)數(shù),并將上述總字節(jié)數(shù)之和作為整體緩沖區(qū)的預(yù)估容量。其中,預(yù)估各屬性值的序列化結(jié)果所占用的總字節(jié)數(shù)是確定整體緩沖區(qū)的預(yù)估容量的關(guān)鍵。
根據(jù)一種實(shí)施例,在預(yù)估一個(gè)屬性值的序列化結(jié)果所占用的字節(jié)數(shù)時(shí),對(duì)于所占用的存儲(chǔ)空間固定的數(shù)據(jù)類(lèi)型,將該數(shù)據(jù)類(lèi)型的數(shù)據(jù)的序列化結(jié)果所能占用的最大字節(jié)數(shù)作為該屬性值的序列化結(jié)果所占用的字節(jié)數(shù)。例如,byte類(lèi)型所占用的存儲(chǔ)空間固定為1個(gè)字節(jié),其存儲(chǔ)的數(shù)值范圍為0~255,故byte類(lèi)型數(shù)據(jù)的序列化結(jié)果所能占用的最大字節(jié)數(shù)為3(以255為例,數(shù)值255的序列化結(jié)果為長(zhǎng)度為3的字符串“255”),因此,容量估計(jì)模塊420在預(yù)估整體緩沖區(qū)的容量時(shí),將byte類(lèi)型的屬性值的序列化結(jié)果所占用的字節(jié)數(shù)設(shè)為3。又例如,int類(lèi)型所占用的存儲(chǔ)空間固定為4個(gè)字節(jié),其存儲(chǔ)的數(shù)值范圍為-2147483648~2147483647,故int類(lèi)型數(shù)據(jù)的序列化結(jié)果所能占用的最大字節(jié)數(shù)為11(以-2147483648為例,數(shù)值-2147483648的序列化結(jié)果為長(zhǎng)度為11的字符串“-2147483648”),因此,容量估計(jì)模塊420在預(yù)估整體緩沖區(qū)的容量時(shí),將int類(lèi)型的屬性值的序列化結(jié)果所占用的字節(jié)數(shù)設(shè)為11。又例如,guid類(lèi)型所占用的存儲(chǔ)空間為16個(gè)字節(jié),其存儲(chǔ)的數(shù)據(jù)為“xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”格式,其中,每個(gè)x表示一個(gè)十六進(jìn)制數(shù),故guid類(lèi)型數(shù)據(jù)的序列化結(jié)果所占用的字節(jié)數(shù)為36。同理可知,容量估計(jì)模塊420在預(yù)估整體緩沖區(qū)的容量時(shí),將sbyte類(lèi)型的屬性值的序列化結(jié)果所占用的字節(jié)數(shù)設(shè)為4,short類(lèi)型的設(shè)為6,float類(lèi)型設(shè)為16,double類(lèi)型設(shè)為25,等等。
對(duì)于所占用的存儲(chǔ)空間不固定但是能夠獲取屬性值長(zhǎng)度的數(shù)據(jù)類(lèi)型,獲取該屬性值的長(zhǎng)度,根據(jù)所述長(zhǎng)度來(lái)確定該屬性值的序列化結(jié)果所占用的字節(jié)數(shù)。例如,string類(lèi)型所占用的存儲(chǔ)空間不確定,但是可以通過(guò)length()方法來(lái)獲取string類(lèi)型的屬性值的長(zhǎng)度,例如,string x=“abc”,那么可以通過(guò)x.length()來(lái)獲取字符串x的長(zhǎng)度,為3,相應(yīng)地,容量估計(jì)模塊420將該屬性值的序列化結(jié)果所占用的字節(jié)數(shù)設(shè)為3。
容量估計(jì)模塊420按照上述方法預(yù)估得出各屬性值的序列化結(jié)果所占用的總字節(jié)數(shù)之后,加上各屬性名、分隔符、標(biāo)識(shí)符所占用的總字節(jié)數(shù),即得到整體緩沖區(qū)的預(yù)估容量。容量估計(jì)模塊420根據(jù)對(duì)象中各屬性的屬性信息來(lái)預(yù)估整體緩沖區(qū)的容量,一次性申請(qǐng)內(nèi)存,避免了多次生成新對(duì)象并拋棄以及對(duì)緩沖區(qū)進(jìn)行多次擴(kuò)容所造成的性能消耗。同時(shí),這種整體緩沖區(qū)的分配方法能夠保證數(shù)據(jù)的寫(xiě)入不會(huì)越界,因此,根據(jù)一種實(shí)施例,可以直接采用指針來(lái)寫(xiě)入數(shù)據(jù),避免語(yǔ)言框架的邊界檢查所造成的性能消耗。
容量估計(jì)模塊420確定了整體緩沖區(qū)的預(yù)估容量后,由緩沖區(qū)請(qǐng)求模塊430向操作系統(tǒng)請(qǐng)求具有預(yù)估容量的整體緩沖區(qū),操作系統(tǒng)響應(yīng)于該請(qǐng)求將分配一塊長(zhǎng)度為預(yù)估容量的內(nèi)存作為整體緩沖區(qū)。隨后,由序列化模塊440依次根據(jù)各屬性的類(lèi)型對(duì)各屬性進(jìn)行序列化,并將序列化后的結(jié)果寫(xiě)入整體緩沖區(qū)。
根據(jù)一種實(shí)施例,序列化模塊440按照屬性在對(duì)象中出現(xiàn)的順序依次對(duì)各屬性進(jìn)行序列化。對(duì)于每個(gè)屬性,先將標(biāo)識(shí)符、屬性名、分隔符寫(xiě)入整體緩沖區(qū),再根據(jù)該屬性的數(shù)據(jù)類(lèi)型對(duì)屬性值進(jìn)行序列化,將序列化結(jié)果寫(xiě)入整體緩沖區(qū)。
在對(duì)屬性值進(jìn)行序列化時(shí),不同數(shù)據(jù)類(lèi)型的屬性值需要不同的序列化方法。根據(jù)一種實(shí)施例,采用動(dòng)態(tài)編譯框架對(duì)屬性值進(jìn)行序列化,即預(yù)先生成好對(duì)每種數(shù)據(jù)類(lèi)型的屬性值進(jìn)行序列化的方法調(diào)用,例如將int類(lèi)型的屬性值的序列化方法設(shè)為Write(int),將string類(lèi)型的屬性值的序列化方法設(shè)為Write(string),等等。在對(duì)某個(gè)屬性值進(jìn)行序列化時(shí),首先通過(guò)動(dòng)態(tài)編譯獲取該屬性的數(shù)據(jù)類(lèi)型,隨后根據(jù)數(shù)據(jù)類(lèi)型來(lái)調(diào)用相應(yīng)的序列化方法對(duì)該屬性值進(jìn)行序列化。該對(duì)象序列化方法是一個(gè)順序執(zhí)行的過(guò)程,無(wú)需采用反射機(jī)制,也無(wú)需進(jìn)行多條件分支判斷,節(jié)省了系統(tǒng)資源,提高了序列化效率。
特別地,在對(duì)屬性值進(jìn)行序列化時(shí),若屬性值的序列化結(jié)果所占用的字節(jié)數(shù)是確定的,例如string類(lèi)型的屬性值,按照從該屬性值的第一位到最后一位的順序依次序列化該屬性值,在將該屬性值的序列化結(jié)果寫(xiě)入時(shí),在整體緩沖區(qū)中的相應(yīng)區(qū)域從前向后寫(xiě)即可。例如,對(duì)于屬性string x=“abc”,其數(shù)據(jù)類(lèi)型為string,在對(duì)string類(lèi)型的屬性值“abc”進(jìn)行序列化時(shí),如圖5A所示,依次序列化a、b、c三個(gè)字符,并將a、b、c三個(gè)字符依次寫(xiě)入整體緩沖區(qū)。
若屬性值的序列化結(jié)果所占用的字節(jié)數(shù)是預(yù)估的(即該屬性值所對(duì)應(yīng)的數(shù)據(jù)類(lèi)型所占用的存儲(chǔ)空間是固定的),則先在該屬性名后跟的分隔符后的第一個(gè)字節(jié)開(kāi)始,為該屬性值的序列化結(jié)果預(yù)留一個(gè)固定區(qū)域,該固定區(qū)域的長(zhǎng)度為該屬性值的序列化結(jié)果所預(yù)估的字節(jié)數(shù)。按照從該屬性值的低位到高位的順序依次序列化該屬性值,在將該屬性值的序列化結(jié)果進(jìn)行寫(xiě)入時(shí),將序列化結(jié)果從固定區(qū)域的后端開(kāi)始寫(xiě)入,在屬性值的序列化完成后,將該屬性值的序列化結(jié)果再移至固定區(qū)域的前端。例如,如圖5B所示,對(duì)于屬性int num=18的屬性值18,在預(yù)估容量時(shí),為一個(gè)int類(lèi)型的值分配的字節(jié)數(shù)為11,因此在對(duì)該屬性值進(jìn)行序列化時(shí),首先為其分配一個(gè)長(zhǎng)度為11字節(jié)的固定區(qū)域(圖5B中的灰色區(qū)域),隨后從低位,即從數(shù)字8開(kāi)始對(duì)其進(jìn)行序列化,將數(shù)字8的序列化結(jié)果寫(xiě)入固定區(qū)域的最后端,隨后對(duì)數(shù)字1進(jìn)行序列化,將數(shù)字1的序列化結(jié)果寫(xiě)入固定區(qū)域的次后端,完成對(duì)屬性值18的序列化后,將序列化結(jié)果(即字符串18)移至固定區(qū)域的前端。如圖5C所示,對(duì)于屬性int num=123456789的屬性值123456789,其序列化過(guò)程與屬性值18類(lèi)似,也是按照從低位到高位的順序進(jìn)行序列化,并按照從固定區(qū)域的后端到前端的順序?qū)懭?,最后再將序列化結(jié)果移動(dòng)至固定區(qū)域的前端。
但是,對(duì)于18和123456789來(lái)說(shuō),圖5B和圖5C所示的序列化過(guò)程效率是不一樣的。屬性值18僅有2位數(shù)字,但在其序列化過(guò)程中每位數(shù)字均需要平移9個(gè)位置才能將其序列化結(jié)果從固定區(qū)域的后端移至前端。而實(shí)際上,由于屬性值18的位數(shù)很少,直接按照從高位到低位的順序進(jìn)行序列化,并從固定區(qū)域的前端寫(xiě)起,可以避免整體緩沖區(qū)中的數(shù)據(jù)移動(dòng),能夠明顯地提高序列化效率。因此,根據(jù)一種優(yōu)選的實(shí)施例,當(dāng)數(shù)據(jù)類(lèi)型為整數(shù)類(lèi)型(例如byte、int、short、long等)時(shí),可以按照以下步驟來(lái)對(duì)屬性值進(jìn)行序列化并將序列化結(jié)果寫(xiě)入整體緩沖區(qū):
若屬性值小于閾值,則按照從高位到低位的順序依次序列化所述屬性值的每一位數(shù)據(jù),將每一位數(shù)據(jù)的序列化結(jié)果依次寫(xiě)入整體緩沖區(qū)的固定區(qū)域,所述固定區(qū)域?yàn)閺姆指舴蟮谝粋€(gè)字節(jié)開(kāi)始的長(zhǎng)度為該類(lèi)型數(shù)據(jù)的序列化結(jié)果所能占用的最大字節(jié)數(shù)的區(qū)域,其中,將屬性值的最高位數(shù)據(jù)的序列化結(jié)果寫(xiě)入固定區(qū)域的第一位,將屬性值的次高位數(shù)據(jù)的序列化結(jié)果寫(xiě)入固定區(qū)域的第二位,以此類(lèi)推;
若屬性值大于等于閾值,則按照從低位到高位的順序依次序列化所述屬性值的每一位數(shù)據(jù),將每一位數(shù)據(jù)的序列化結(jié)果依次寫(xiě)入整體緩沖區(qū)的固定區(qū)域,其中,將屬性值的最低位數(shù)據(jù)的序列化結(jié)果寫(xiě)入固定區(qū)域的最后一位,將屬性值的次低位數(shù)據(jù)的序列化結(jié)果寫(xiě)入固定區(qū)域的倒數(shù)第二位,以此類(lèi)推;在屬性值的序列化結(jié)果全部寫(xiě)入固定區(qū)域后,將屬性值的序列化結(jié)果移至固定區(qū)域的最前端。
上述閾值的取值應(yīng)為10的整數(shù)倍,且一般為一個(gè)比較小的數(shù),例如100。當(dāng)然,閾值的設(shè)置可以由本領(lǐng)域技術(shù)人員根據(jù)實(shí)際情況自行設(shè)置,例如,對(duì)于int類(lèi)型將閾值設(shè)置為100,對(duì)于long類(lèi)型將閾值設(shè)置為10000,等等,本發(fā)明對(duì)閾值的具體取值不做限制。
在采用上述優(yōu)化后,例如將int類(lèi)型的閾值設(shè)為100,則對(duì)于屬性值18和屬性值123456789,其序列化過(guò)程分別如圖6A、6B所示。其中,圖6A所示的小于閾值100的屬性值18的序列化過(guò)程與圖5B中所示不同,其序列化效率有明顯提高;圖6B所示的大于100的屬性值123456789的序列化過(guò)程仍與圖5C中所示相同。
應(yīng)當(dāng)指出,圖6A、6B所示的優(yōu)化邏輯體現(xiàn)在對(duì)整數(shù)類(lèi)型數(shù)值的方法調(diào)用上,即體現(xiàn)在Write(int)、Write(long)、Write(short)等方法中。
序列化模塊440完成對(duì)象中所有屬性的序列化后,即完成了整個(gè)對(duì)象的序列化,這時(shí),整體緩沖區(qū)中存儲(chǔ)的內(nèi)容即為對(duì)象序列化的結(jié)果。
圖7示出了根據(jù)本發(fā)明另一個(gè)實(shí)施例的對(duì)象序列化裝置700的結(jié)構(gòu)圖。其與圖4所示的裝置400相比,多了回收模塊450。信息獲取模塊410、容量預(yù)估模塊420和序列化模塊440的功能和處理邏輯與在前述裝置400中所述的相同,此處不再贅述。
回收模塊450適于在完成對(duì)象序列化之后,對(duì)整體緩沖區(qū)進(jìn)行回收以實(shí)現(xiàn)緩沖區(qū)重用。在為下一次對(duì)象序列化分配整體緩沖區(qū)時(shí),緩沖區(qū)請(qǐng)求模塊430首先在已回收的緩沖區(qū)中請(qǐng)求整體緩沖區(qū),即:判斷現(xiàn)有的緩沖區(qū)中是否存在容量大于等于所述預(yù)估容量的緩沖區(qū);若是,則將所述緩沖區(qū)作為本次對(duì)象序列化的整體緩沖區(qū);若否,則向操作系統(tǒng)請(qǐng)求具有所述預(yù)估容量的整體緩沖區(qū)。
回收模塊450能夠在完成對(duì)象序列化之后對(duì)整體緩沖區(qū)進(jìn)行回收,統(tǒng)一管理。從而在為下一次對(duì)象序列化分配整體緩沖區(qū)時(shí),優(yōu)先使用已有的緩沖區(qū)進(jìn)行分配,無(wú)需向操作系統(tǒng)重新申請(qǐng)內(nèi)存,減少了CPU的負(fù)擔(dān)。對(duì)于預(yù)估容量較大的整體緩沖區(qū)分配,該方案的性能優(yōu)勢(shì)體現(xiàn)得更為明顯。
圖8示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的對(duì)象序列化方法800的流程圖。如圖8所示,該方法始于步驟S810。
在步驟S810中,依次獲取對(duì)象中各屬性的屬性信息。其中,“依次”指的是按照屬性在對(duì)象中出現(xiàn)的順序依次獲取對(duì)象中的屬性信息,即首先獲取對(duì)象中出現(xiàn)的第一個(gè)屬性的屬性信息,再獲取對(duì)象中出現(xiàn)的第二個(gè)屬性的屬性信息,以此類(lèi)推。屬性信息包括數(shù)據(jù)類(lèi)型、屬性名和屬性值。
隨后,在步驟S820中,根據(jù)各屬性的屬性信息來(lái)確定整體緩沖區(qū)的預(yù)估容量。確定整體緩沖區(qū)的預(yù)估容量的具體步驟可以參見(jiàn)前述對(duì)容量預(yù)估模塊420的描述,此處不再贅述。
隨后,在步驟S830中,向操作系統(tǒng)請(qǐng)求具有所述預(yù)估容量的整體緩沖區(qū)。操作系統(tǒng)響應(yīng)于該請(qǐng)求,將分配一塊長(zhǎng)度為預(yù)估容量的內(nèi)存作為整體緩沖區(qū)。
隨后,在步驟S840中,依次根據(jù)各屬性的數(shù)據(jù)類(lèi)型對(duì)各屬性進(jìn)行序列化,將序列化后的結(jié)果寫(xiě)入整體緩沖區(qū)。該步驟的具體過(guò)程可以參見(jiàn)前述對(duì)序列化模塊440的描述,此處不再贅述。
圖9示出了根據(jù)本發(fā)明另一個(gè)實(shí)施例的對(duì)象序列化方法900的流程圖。該方法始于步驟S910。
在步驟S910中,依次獲取對(duì)象中各屬性的屬性信息。該步驟與前述方法800中的步驟S810相同,此處不再贅述。
隨后,在步驟S920中,根據(jù)各屬性的屬性信息來(lái)確定整體緩沖區(qū)的預(yù)估容量。該步驟與前述方法800中的步驟S820相同,此處不再贅述。
隨后,在步驟S930中,判斷現(xiàn)有的緩沖區(qū)中是否存在容量大于等于預(yù)估容量的緩沖區(qū),若是,則執(zhí)行步驟S940,將該容量大于等于預(yù)估容量的緩沖區(qū)作為本次對(duì)象序列化的整體緩沖區(qū);若否,則執(zhí)行步驟S950,向操作系統(tǒng)請(qǐng)求具有預(yù)估容量的整體緩沖區(qū)。
隨后,在步驟S960中,依次根據(jù)各屬性的數(shù)據(jù)類(lèi)型對(duì)各屬性進(jìn)行序列化,將序列化后的結(jié)果寫(xiě)入整體緩沖區(qū)。該步驟與前述方法800中的步驟S840相同,此處不再贅述。
隨后,在步驟S970中,對(duì)整體緩沖區(qū)進(jìn)行回收。該步驟的具體過(guò)程可以參見(jiàn)前述對(duì)回收模塊450的描述,此處不再贅述。
通過(guò)前述的一系列優(yōu)化,本發(fā)明的對(duì)象序列化方案與現(xiàn)有的主流技術(shù)方案相比,對(duì)于JSON等文本類(lèi)型序列化的時(shí)間性能能夠提升10倍,相對(duì)于其他Json.Net等第三方Json序列化方案更是有高達(dá)20多倍的性能提升。對(duì)于二進(jìn)制序列化,性能的提升會(huì)更加明顯,其相對(duì)于現(xiàn)有的技術(shù)方案的時(shí)間性能能夠提升20~30倍。
應(yīng)當(dāng)指出,雖然前面的描述以JSON為例,但是,本發(fā)明的對(duì)象序列化方案也可以適用于以二進(jìn)制為目標(biāo)格式序列化。根據(jù)本發(fā)明的目標(biāo)格式為二進(jìn)制的對(duì)象序列化方法的步驟與JSON目標(biāo)格式的對(duì)象序列化方法類(lèi)似:首先,依次獲取對(duì)象中各屬性的屬性信息,所述屬性信息包括數(shù)據(jù)類(lèi)型、屬性名和屬性值,該步驟與JSON序列化相同。隨后,根據(jù)各屬性的屬性信息來(lái)確定整體緩沖區(qū)的預(yù)估容量。在二進(jìn)制序列化中,屬性名與屬性值的序列化一般分別進(jìn)行,二者的序列化結(jié)果分別存儲(chǔ)于不同的文檔,因此,對(duì)于二進(jìn)制序列化,在確定整體緩沖區(qū)的預(yù)估容量時(shí),僅需預(yù)估屬性值的序列化結(jié)果所占用的字節(jié)數(shù)即可。二進(jìn)制下的字節(jié)數(shù)預(yù)估相對(duì)于JSON來(lái)說(shuō)更為簡(jiǎn)單,屬性值的序列化結(jié)果所占用的字節(jié)數(shù)與該屬性值原本所占用的存儲(chǔ)空間相同,例如,byte類(lèi)型所占用的存儲(chǔ)空間為1個(gè)字節(jié),那么byte類(lèi)型的屬性值的二進(jìn)制序列化結(jié)果也占1個(gè)字節(jié);int類(lèi)型所占用的存儲(chǔ)空間為4個(gè)字節(jié),那么int類(lèi)型的屬性值的二進(jìn)制序列化結(jié)果也占4個(gè)字節(jié);string類(lèi)型的屬性值得序列化結(jié)果所占用的字節(jié)數(shù)與該屬性值的字符長(zhǎng)度等同;datetime的二進(jìn)制序列化結(jié)果占用8個(gè)字節(jié);guid的二進(jìn)制序列化結(jié)果占用16個(gè)字節(jié),等等。在確定了整體緩沖區(qū)的預(yù)估容量后,向操作系統(tǒng)請(qǐng)求具有所述預(yù)估容量的整體緩沖區(qū)。在操作系統(tǒng)相應(yīng)于該請(qǐng)求分配了整體緩沖區(qū)后,依次對(duì)各屬性值進(jìn)行序列化,并將序列化后的結(jié)果寫(xiě)入整體緩沖區(qū)。
應(yīng)當(dāng)指出,本發(fā)明在預(yù)估屬性值的序列化結(jié)果所占用的字節(jié)數(shù)時(shí),僅適用于所占用的存儲(chǔ)空間固定的,或者所占用的存儲(chǔ)空間不固定但是能夠方便地獲取屬性值長(zhǎng)度的數(shù)據(jù)類(lèi)型。對(duì)于難以預(yù)估序列化結(jié)果所占用的字節(jié)數(shù)的數(shù)據(jù)類(lèi)型,仍采用現(xiàn)有技術(shù)的方案,即動(dòng)態(tài)分配緩沖區(qū)的方案,邊序列化邊擴(kuò)容。例如,對(duì)于dictionary<int,int>的數(shù)據(jù)類(lèi)型,其相當(dāng)于一個(gè)int類(lèi)型的集合,該類(lèi)型的屬性值的序列化結(jié)果所占用的字節(jié)數(shù)可以參照int類(lèi)型的預(yù)估方法來(lái)預(yù)估,因而該類(lèi)型可以適用于本發(fā)明所述的對(duì)象序列化方案。而對(duì)于dictionary<int,object>的數(shù)據(jù)類(lèi)型,由于其中包含object對(duì)象,難以準(zhǔn)確預(yù)估該屬性值的序列化結(jié)果所占用的字節(jié)數(shù),因此該屬性值不適用于本發(fā)明所述的對(duì)象序列化方案,而采用現(xiàn)有技術(shù)中的動(dòng)態(tài)擴(kuò)容方案對(duì)其進(jìn)行序列化。
下面結(jié)合一個(gè)JSON序列化的具體例子來(lái)說(shuō)明本發(fā)明的對(duì)象序列化步驟。
定義Student類(lèi)如下:
首先,根據(jù)各屬性的屬性信息來(lái)確定整體緩沖區(qū)的預(yù)估容量。屬性名Number、Name、Age共占用13個(gè)字節(jié)。Number是一個(gè)int類(lèi)型的屬性,其屬性值的序列化結(jié)果占用11個(gè)字節(jié);Name是一個(gè)string類(lèi)型的屬性,其屬性值的長(zhǎng)度可以通過(guò)Length()方法確定,該屬性值的序列化結(jié)果占用8個(gè)字節(jié);Age是一個(gè)int類(lèi)型的屬性,其屬性值的序列化結(jié)果占用11個(gè)字節(jié),故預(yù)估屬性值的序列化結(jié)果共占用11+8+11=30個(gè)字節(jié)。該對(duì)象包括三個(gè)屬性,故其序列化結(jié)果中有3個(gè)冒號(hào)(:)分隔符和2個(gè)逗號(hào)(,)分隔符,共占用5個(gè)字節(jié);該對(duì)象包括三個(gè)屬性,且其中有一個(gè)屬性為字符類(lèi)型,故其序列化結(jié)果中有4對(duì)雙引號(hào)(“”)標(biāo)識(shí)符,同時(shí),整個(gè)序列化結(jié)果用一對(duì)大括號(hào)({})所標(biāo)識(shí),故標(biāo)識(shí)符共占用10個(gè)字節(jié),故分隔符和標(biāo)識(shí)符共占用5+10=15個(gè)字節(jié)。因此,整體緩沖區(qū)的預(yù)估容量為13+30+15=58個(gè)字節(jié)。
判斷現(xiàn)有的緩沖區(qū)中是否存在容量大于等于58個(gè)字節(jié)的緩沖區(qū),若有,則將該緩沖區(qū)作為本次對(duì)象序列化的整體緩沖區(qū);若沒(méi)有,則向操作系統(tǒng)請(qǐng)求具有所述預(yù)估容量的整體緩沖區(qū)。此處,假設(shè)現(xiàn)有的緩沖區(qū)中不存在容量大于等于58個(gè)字節(jié)的緩沖區(qū),那么由操作系統(tǒng)來(lái)分配一塊長(zhǎng)58字節(jié)的內(nèi)存作為整體緩沖區(qū)。
隨后依次對(duì)各屬性進(jìn)行序列化,序列化過(guò)程如圖10所示。首先序列化第一個(gè)屬性,將標(biāo)識(shí)符左大括號(hào)({)、標(biāo)識(shí)符左引號(hào)(“)、屬性名Number、標(biāo)識(shí)符右引號(hào)(”)、分隔符冒號(hào)(:)依次寫(xiě)入整體緩沖區(qū)。隨后對(duì)第一個(gè)屬性的屬性值進(jìn)行序列化,該屬性的數(shù)據(jù)類(lèi)型為int,在整體緩沖區(qū)為其分配一個(gè)長(zhǎng)度為11個(gè)字節(jié)的固定區(qū)域(圖10中的灰色區(qū)域),假設(shè)此處將int類(lèi)型的閾值設(shè)為100,由于屬性值1234567>100,按照從低位到高位的順序?qū)傩灾?234567進(jìn)行序列化,并將序列化結(jié)果依次寫(xiě)入整體緩沖區(qū)的固定區(qū)域,其中,將屬性值的最低位數(shù)據(jù)7的序列化結(jié)果寫(xiě)入固定區(qū)域的最后一位,將屬性值的次低位數(shù)據(jù)6的序列化結(jié)果寫(xiě)入固定區(qū)域的倒數(shù)第二位,以此類(lèi)推;在屬性值的序列化結(jié)果全部寫(xiě)入固定區(qū)域后,將屬性值的序列化結(jié)果移至固定區(qū)域的最前端,完成第一個(gè)屬性的序列化。
隨后,在第一個(gè)屬性值的序列化結(jié)果后寫(xiě)入分隔符逗號(hào)(,),進(jìn)行第二個(gè)屬性的序列化。將標(biāo)識(shí)符左引號(hào)(“)、屬性名Name、標(biāo)識(shí)符右引號(hào)(”)、分隔符冒號(hào)(:)依次寫(xiě)入整體緩沖區(qū)。隨后對(duì)第二個(gè)屬性的屬性值進(jìn)行序列化,該屬性的數(shù)據(jù)類(lèi)型為string,需要先寫(xiě)入標(biāo)識(shí)符左引號(hào)(“),再依次將“somebody”中的每一個(gè)字符進(jìn)行序列化并寫(xiě)入整體緩沖區(qū)中,最后寫(xiě)入標(biāo)識(shí)符右引號(hào)(”),完成第二個(gè)屬性的序列化。
隨后,在第二個(gè)屬性值的序列化結(jié)果后寫(xiě)入分隔符逗號(hào)(,),進(jìn)行第三個(gè)屬性的序列化。將標(biāo)識(shí)符左引號(hào)(“)、屬性名Age、標(biāo)識(shí)符右引號(hào)(”)、分隔符冒號(hào)(:)依次寫(xiě)入整體緩沖區(qū)。隨后對(duì)第三個(gè)屬性的屬性值進(jìn)行序列化,該屬性的數(shù)據(jù)類(lèi)型為int,在整體緩沖區(qū)為其分配一個(gè)長(zhǎng)度為11個(gè)字節(jié)的固定區(qū)域(圖10中的灰色區(qū)域),由于屬性值18<100,按照從高位到低位的順序?qū)傩灾?8進(jìn)行序列化,并將序列化結(jié)果依次寫(xiě)入整體緩沖區(qū)的固定區(qū)域,其中,將屬性值的最高位數(shù)據(jù)1的序列化結(jié)果寫(xiě)入固定區(qū)域的第一位,將屬性值的次高位數(shù)據(jù)8的序列化結(jié)果寫(xiě)入固定區(qū)域的第二位,即完成第三個(gè)屬性的序列化。
最后,在第三個(gè)屬性值得序列化結(jié)果后寫(xiě)入標(biāo)識(shí)符右大括號(hào)(}),完成整個(gè)對(duì)象的序列化。對(duì)于該對(duì)象,其JSON序列化結(jié)果為:
{“Number”:1234567,“Name”:“somebody”,“Age”:18}
在完成該對(duì)象的序列化后,根據(jù)實(shí)際需要將整體緩沖區(qū)中緩存的對(duì)象序列化結(jié)果輸出或?qū)懭氪疟P(pán)。然后回收該整體緩沖區(qū),以實(shí)現(xiàn)緩沖區(qū)重用。
A6:A4或5所述的對(duì)象序列化方法,其中,當(dāng)數(shù)據(jù)類(lèi)型為整數(shù)類(lèi)型時(shí),所述根據(jù)該屬性的數(shù)據(jù)類(lèi)型對(duì)屬性值進(jìn)行序列化,將序列化結(jié)果寫(xiě)入整體緩沖區(qū)的步驟包括:
若屬性值小于預(yù)設(shè)的閾值,則按照從高位到低位的順序依次序列化所述屬性值的每一位數(shù)據(jù),將每一位數(shù)據(jù)的序列化結(jié)果依次寫(xiě)入整體緩沖區(qū)的固定區(qū)域,所述固定區(qū)域?yàn)閺姆指舴蟮谝粋€(gè)字節(jié)開(kāi)始的、長(zhǎng)度為該類(lèi)型數(shù)據(jù)的序列化結(jié)果所能占用的最大字節(jié)數(shù)的區(qū)域,其中,將屬性值的最高位數(shù)據(jù)的序列化結(jié)果寫(xiě)入固定區(qū)域的第一位,將屬性值的次高位數(shù)據(jù)的序列化結(jié)果寫(xiě)入固定區(qū)域的第二位,以此類(lèi)推;
若屬性值大于等于所述閾值,則按照從低位到高位的順序依次序列化所述屬性值的每一位數(shù)據(jù),將每一位數(shù)據(jù)的序列化結(jié)果依次寫(xiě)入整體緩沖區(qū)的固定區(qū)域,其中,將屬性值的最低位數(shù)據(jù)的序列化結(jié)果寫(xiě)入固定區(qū)域的最后一位,將屬性值的次低位數(shù)據(jù)的序列化結(jié)果寫(xiě)入固定區(qū)域的倒數(shù)第二位,以此類(lèi)推;在屬性值的序列化結(jié)果全部寫(xiě)入固定區(qū)域后,將屬性值的序列化結(jié)果移至固定區(qū)域的最前端。
A7:A1-6中任一項(xiàng)所述的對(duì)象序列化方法,其中,采用指針來(lái)執(zhí)行所述寫(xiě)入的步驟。
A8:A1所述的對(duì)象序列化方法,其中,在完成對(duì)象序列化之后,對(duì)所述整體緩沖區(qū)進(jìn)行回收以實(shí)現(xiàn)緩沖區(qū)重用。
A9:A8所述的對(duì)象序列化方法,在所述向操作系統(tǒng)請(qǐng)求具有所述預(yù)估容量的整體緩沖區(qū)的步驟之前,還包括:
判斷現(xiàn)有的緩沖區(qū)中是否存在容量大于等于所述預(yù)估容量的緩沖區(qū);
若是,則將該容量大于等于所述預(yù)估容量的緩沖區(qū)作為本次對(duì)象序列化的整體緩沖區(qū);
若否,則向操作系統(tǒng)請(qǐng)求具有所述預(yù)估容量的整體緩沖區(qū)。
B14:B13所述的對(duì)象序列化裝置,其中,所述序列化模塊適于按照以下步驟根據(jù)該屬性的數(shù)據(jù)類(lèi)型對(duì)屬性值進(jìn)行序列化:通過(guò)動(dòng)態(tài)編譯獲取該屬性的數(shù)據(jù)類(lèi)型,根據(jù)所獲取的數(shù)據(jù)類(lèi)型調(diào)用相應(yīng)的序列化方法對(duì)該屬性值進(jìn)行序列化。
B15:B13或14所述的對(duì)象序列化裝置,其中,當(dāng)數(shù)據(jù)類(lèi)型為整數(shù)類(lèi)型時(shí),所述序列化模塊適于按照以下步驟來(lái)根據(jù)該屬性的數(shù)據(jù)類(lèi)型對(duì)屬性值進(jìn)行序列化,將序列化結(jié)果寫(xiě)入整體緩沖區(qū):
若屬性值小于預(yù)設(shè)的閾值,則按照從高位到低位的順序依次序列化所述屬性值的每一位數(shù)據(jù),將每一位數(shù)據(jù)的序列化結(jié)果依次寫(xiě)入整體緩沖區(qū)的固定區(qū)域,所述固定區(qū)域?yàn)閺姆指舴蟮谝粋€(gè)字節(jié)開(kāi)始的長(zhǎng)度為該類(lèi)型數(shù)據(jù)的序列化結(jié)果所能占用的最大字節(jié)數(shù)的區(qū)域,其中,將屬性值的最高位數(shù)據(jù)的序列化結(jié)果寫(xiě)入固定區(qū)域的第一位,將屬性值的次高位數(shù)據(jù)的序列化結(jié)果寫(xiě)入固定區(qū)域的第二位,以此類(lèi)推;
若屬性值大于等于所述閾值,則按照從低位到高位的順序依次序列化所述屬性值的每一位數(shù)據(jù),將每一位數(shù)據(jù)的序列化結(jié)果依次寫(xiě)入整體緩沖區(qū)的固定區(qū)域,其中,將屬性值的最低位數(shù)據(jù)的序列化結(jié)果寫(xiě)入固定區(qū)域的最后一位,將屬性值的次低位數(shù)據(jù)的序列化結(jié)果寫(xiě)入固定區(qū)域的倒數(shù)第二位,以此類(lèi)推;在屬性值的序列化結(jié)果全部寫(xiě)入固定區(qū)域后,將屬性值的序列化結(jié)果移至固定區(qū)域的最前端。
B16:B10-15中任一項(xiàng)所述的對(duì)象序列化裝置,其中,所述序列化模塊適于采用指針來(lái)執(zhí)行所述寫(xiě)入的步驟。
B17:B10所述的對(duì)象序列化裝置,其中,還包括回收模塊,適于在完成對(duì)象序列化之后,對(duì)所述整體緩沖區(qū)進(jìn)行回收以實(shí)現(xiàn)緩沖區(qū)重用。
B18:B17所述的對(duì)象序列化裝置,其中,所述緩沖區(qū)請(qǐng)求模塊在向操作系統(tǒng)請(qǐng)求具有所述預(yù)估容量的整體緩沖區(qū)之前,還適于:
判斷現(xiàn)有的緩沖區(qū)中是否存在容量大于等于所述預(yù)估容量的緩沖區(qū);
若是,則將該容量大于等于所述預(yù)估容量的緩沖區(qū)作為本次對(duì)象序列化的整體緩沖區(qū);
若否,則向操作系統(tǒng)請(qǐng)求具有所述預(yù)估容量的整體緩沖區(qū)。
在此處所提供的說(shuō)明書(shū)中,算法和顯示不與任何特定計(jì)算機(jī)、虛擬系統(tǒng)或者其它設(shè)備固有相關(guān)。各種通用系統(tǒng)也可以與本發(fā)明的示例一起使用。根據(jù)上面的描述,構(gòu)造這類(lèi)系統(tǒng)所要求的結(jié)構(gòu)是顯而易見(jiàn)的。此外,本發(fā)明也不針對(duì)任何特定編程語(yǔ)言。應(yīng)當(dāng)明白,可以利用各種編程語(yǔ)言實(shí)現(xiàn)在此描述的本發(fā)明的內(nèi)容,并且上面對(duì)特定語(yǔ)言所做的描述是為了披露本發(fā)明的最佳實(shí)施方式。
在此處所提供的說(shuō)明書(shū)中,說(shuō)明了大量具體細(xì)節(jié)。然而,能夠理解,本發(fā)明的實(shí)施例可以在沒(méi)有這些具體細(xì)節(jié)的情況下被實(shí)踐。在一些實(shí)例中,并未詳細(xì)示出公知的方法、結(jié)構(gòu)和技術(shù),以便不模糊對(duì)本說(shuō)明書(shū)的理解。
類(lèi)似地,應(yīng)當(dāng)理解,為了精簡(jiǎn)本公開(kāi)并幫助理解各個(gè)發(fā)明方面中的一個(gè)或多個(gè),在上面對(duì)本發(fā)明的示例性實(shí)施例的描述中,本發(fā)明的各個(gè)特征有時(shí)被一起分組到單個(gè)實(shí)施例、圖、或者對(duì)其的描述中。然而,并不應(yīng)將該公開(kāi)的方法解釋成反映如下意圖:即所要求保護(hù)的本發(fā)明要求比在每個(gè)權(quán)利要求中所明確記載的特征更多特征。更確切地說(shuō),如下面的權(quán)利要求書(shū)所反映的那樣,發(fā)明方面在于少于前面公開(kāi)的單個(gè)實(shí)施例的所有特征。因此,遵循具體實(shí)施方式的權(quán)利要求書(shū)由此明確地并入該具體實(shí)施方式,其中每個(gè)權(quán)利要求本身都作為本發(fā)明的單獨(dú)實(shí)施例。
本領(lǐng)域那些技術(shù)人員應(yīng)當(dāng)理解在本文所公開(kāi)的示例中的設(shè)備的模塊或單元或組件可以布置在如該實(shí)施例中所描述的設(shè)備中,或者可替換地可以定位在與該示例中的設(shè)備不同的一個(gè)或多個(gè)設(shè)備中。前述示例中的模塊可以組合為一個(gè)模塊或者此外可以分成多個(gè)子模塊。
本領(lǐng)域那些技術(shù)人員可以理解,可以對(duì)實(shí)施例中的設(shè)備中的模塊進(jìn)行自適應(yīng)性地改變并且把它們?cè)O(shè)置在與該實(shí)施例不同的一個(gè)或多個(gè)設(shè)備中??梢园褜?shí)施例中的模塊或單元或組件組合成一個(gè)模塊或單元或組件,以及此外可以把它們分成多個(gè)子模塊或子單元或子組件。除了這樣的特征和/或過(guò)程或者單元中的至少一些是相互排斥之外,可以采用任何組合對(duì)本說(shuō)明書(shū)(包括伴隨的權(quán)利要求、摘要和附圖)中公開(kāi)的所有特征以及如此公開(kāi)的任何方法或者設(shè)備的所有過(guò)程或單元進(jìn)行組合。除非另外明確陳述,本說(shuō)明書(shū)(包括伴隨的權(quán)利要求、摘要和附圖)中公開(kāi)的每個(gè)特征可以由提供相同、等同或相似目的的替代特征來(lái)代替。
此外,本領(lǐng)域的技術(shù)人員能夠理解,盡管在此所述的一些實(shí)施例包括其它實(shí)施例中所包括的某些特征而不是其它特征,但是不同實(shí)施例的特征的組合意味著處于本發(fā)明的范圍之內(nèi)并且形成不同的實(shí)施例。例如,在下面的權(quán)利要求書(shū)中,所要求保護(hù)的實(shí)施例的任意之一都可以以任意的組合方式來(lái)使用。
此外,所述實(shí)施例中的一些在此被描述成可以由計(jì)算機(jī)系統(tǒng)的處理器或者由執(zhí)行所述功能的其它裝置實(shí)施的方法或方法元素的組合。因此,具有用于實(shí)施所述方法或方法元素的必要指令的處理器形成用于實(shí)施該方法或方法元素的裝置。此外,裝置實(shí)施例的在此所述的元素是如下裝置的例子:該裝置用于實(shí)施由為了實(shí)施該發(fā)明的目的的元素所執(zhí)行的功能。
如在此所使用的那樣,除非另行規(guī)定,使用序數(shù)詞“第一”、“第二”、“第三”等等來(lái)描述普通對(duì)象僅僅表示涉及類(lèi)似對(duì)象的不同實(shí)例,并且并不意圖暗示這樣被描述的對(duì)象必須具有時(shí)間上、空間上、排序方面或者以任意其它方式的給定順序。
盡管根據(jù)有限數(shù)量的實(shí)施例描述了本發(fā)明,但受益于上面的描述,本技術(shù)領(lǐng)域內(nèi)的技術(shù)人員明白,在由此描述的本發(fā)明的范圍內(nèi),可以設(shè)想其它實(shí)施例。此外,應(yīng)當(dāng)注意,本說(shuō)明書(shū)中使用的語(yǔ)言主要是為了可讀性和教導(dǎo)的目的而選擇的,而不是為了解釋或者限定本發(fā)明的主題而選擇的。因此,在不偏離所附權(quán)利要求書(shū)的范圍和精神的情況下,對(duì)于本技術(shù)領(lǐng)域的普通技術(shù)人員來(lái)說(shuō)許多修改和變更都是顯而易見(jiàn)的。對(duì)于本發(fā)明的范圍,對(duì)本發(fā)明所做的公開(kāi)是說(shuō)明性的,而非限制性的,本發(fā)明的范圍由所附權(quán)利要求書(shū)限定。