欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang利用位運算實現(xiàn)為程序加速

 更新時間:2022年08月02日 15:07:46   作者:crossoverJie  
這篇文章主要為大家詳細介紹了如何在Golang中利用位運算實現(xiàn)為程序加速功能,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下

前言

最近在持續(xù)優(yōu)化之前編寫的 JSON 解析庫 xjson,主要是兩個方面的優(yōu)化。

第一個是支持將一個 JSONObject 對象輸出為 JSON 字符串。

這點在上個版本中只是利用自帶的 Print 函數(shù)打印數(shù)據(jù):

func TestJson4(t *testing.T)  {
	str := `{"people":{"name":{"first":"bob"}}}`
	first := xjson.Get(str, "people.name.first")
	assert.Equal(t, first.String(), "bob")
	get := xjson.Get(str, "people")
	fmt.Println(get.String())
	//assert.Equal(t, get.String(),`{"name":{"first":"bob"}}`)
}

Output:

map[name:map[first:bob]]

本次優(yōu)化之后便能直接輸出 JSON 字符串了:

實現(xiàn)過程也很簡單,只需要遞歸遍歷 object 中的數(shù)據(jù),然后拼接字符串即可,核心代碼如下:

func (r Result) String() string {
	switch r.Token {
	case String:
		return fmt.Sprint(r.object)
	case Bool:
		return fmt.Sprint(r.object)
	case Number:
		i, _ := strconv.Atoi(fmt.Sprint(r.object))
		return fmt.Sprintf("%d", i)
	case Float:
		i, _ := strconv.ParseFloat(fmt.Sprint(r.object), 64)
		return fmt.Sprintf("%f", i)
	case JSONObject:
		return object2JSONString(r.object)
	case ArrayObject:
		return object2JSONString(r.Array())
	default:
		return ""
	}
}

用位運算優(yōu)化

第二個優(yōu)化主要是提高了性能,查詢一個復雜 JSON 數(shù)據(jù)的時候性能提高了大約 ?16%.

# 優(yōu)化前
BenchmarkDecode-12         90013             66905 ns/op           42512 B/op       1446 allocs/op

# 優(yōu)化后
BenchmarkDecode-12        104746             59766 ns/op           37749 B/op       1141 allocs/op

這里截取了一些重點改動的部分:

在 JSON 解析過程中會有一個有限狀態(tài)機狀態(tài)遷移的過程,而遷移的時候可能會出現(xiàn)多個狀態(tài)。

比如當前解析到的 token 值為 {,那它接下來的 token 可能會為 ObjectKey:"name",也可能會是 BeginObject:{,當然也可能會是 EndObject:}
所以在優(yōu)化之前我是將狀態(tài)全部存放在一個集合中的,在解析過程中如果發(fā)現(xiàn)狀態(tài)不滿足預期的列表時則會拋出語法異常的錯誤。

所以優(yōu)化之前是遍歷這個集合來進行判斷的,這樣的時間復雜度為 O(N),但當我們換成位運算就不一樣了,時間復雜度直接就變?yōu)?code>O(1)了,同時還節(jié)省了一個切片的存儲空間。

我們簡單來分析下這個位運算為什么會達到判斷一個數(shù)據(jù)是否在一個集合中同樣的效果。

首先以這兩個狀態(tài)為例:

	StatusObjectKey   status = 0x0002
	StatusColon       status = 0x0004

他們分別對應的二進制數(shù)據(jù)為:

	StatusObjectKey   status = 0x0002 //0010
	StatusColon       status = 0x0004 //0100

當我們對這兩個數(shù)據(jù)求 | 運算得到的數(shù)據(jù)是 0110

A:0010
B:0100

C:0110

這時候如何我們如果用這兩個原始數(shù)據(jù)與 C:0110 做 & 運算時就會還原為剛才的兩個數(shù)據(jù)。

// input:
A:0010
C:0110

// output:
A:0010

----------
// input:
B:0100
C:0110

// output:
B:0100

但我們換一個 D 與 C 求 & 時:

D: 1000 // 0x0008 對應的二進制為 1000
C: 0110
D':0000

將會得到一個 0 值,只要得出的數(shù)據(jù)大于 0 我們就能判斷一個數(shù)據(jù)是否在給定的集合中了。

當然這里有一個前提條件就是,我們輸入的數(shù)據(jù)高位永遠都是是 1 才行,也就是2的冪。

同樣的優(yōu)化在解析查詢語法時也有使用:

其他奇淫巧技

當然位運算還有一些其他技巧,比如判斷奇偶數(shù):

// 偶數(shù)
a & 1 == 0

// 奇數(shù)
a & 1 == 1

乘法和除法,右移1一位是除以2,左移一位是乘以2.

x := 2
fmt.Println(x>>1) //1
fmt.Println(x<<1) //4

總結

位運算在帶來程序性能提升的同時也降低代碼可讀性,所以我們得按需選擇是否使用;

再一些底層庫、框架代碼對性能有極致追求的場景推薦使用,但在業(yè)務代碼中對數(shù)據(jù)做加減乘除就沒必要用位運算了,只會讓后續(xù)的維護者一臉懵逼。

到此這篇關于Golang利用位運算實現(xiàn)為程序加速的文章就介紹到這了,更多相關Golang位運算內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Golang?Gin?中間件?Next()方法示例詳解

    Golang?Gin?中間件?Next()方法示例詳解

    這篇文章主要介紹了Golang?Gin?中間件?Next()方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04
  • Golang爬蟲框架colly使用淺析

    Golang爬蟲框架colly使用淺析

    這篇文章主要介紹了Golang爬蟲框架colly的使用,colly是Go實現(xiàn)的比較有名的一款爬蟲框架,而且Go在高并發(fā)和分布式場景的優(yōu)勢也正是爬蟲技術所需要的,感興趣想要詳細了解可以參考下文
    2023-05-05
  • 利用golang實現(xiàn)pdf中自動換行的表格

    利用golang實現(xiàn)pdf中自動換行的表格

    這篇文章主要給大家介紹了如何利用golang實現(xiàn)pdf中自動換行的表格,文中通過代碼示例給大家講解的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-02-02
  • Hugo 游樂場內容初始化示例詳解

    Hugo 游樂場內容初始化示例詳解

    這篇文章主要為大家介紹了Hugo 游樂場內容初始化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • Go實現(xiàn)mongodb增刪改查工具類的代碼示例

    Go實現(xiàn)mongodb增刪改查工具類的代碼示例

    這篇文章主要給大家介紹了關于Go實現(xiàn)mongodb增刪改查工具類的相關資料,MongoDB是一個NoSQL數(shù)據(jù)庫,它提供了靈活的文檔存儲模型以及強大的查詢和操作功能,需要的朋友可以參考下
    2023-10-10
  • 深入Go goroutine理解

    深入Go goroutine理解

    這篇文章主要介紹了深入Go goroutine理解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-02-02
  • GO使用Mutex確保并發(fā)程序正確性詳解

    GO使用Mutex確保并發(fā)程序正確性詳解

    這篇文章主要為大家介紹了GO使用Mutex確保并發(fā)程序正確性詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • Go1.18都出泛型了速來圍觀

    Go1.18都出泛型了速來圍觀

    泛型允許程序員在強類型程序設計語言中編寫代碼時使用一些以后才指定的類型,在實例化時作為參數(shù)指明這些類型,本文通過例子給大家介紹下如何使用泛型,對Go1.18泛型相關知識感興趣的朋友一起看看吧
    2022-03-03
  • Go語言學習之new函數(shù)的用法詳解

    Go語言學習之new函數(shù)的用法詳解

    這篇文章主要為大家詳細介紹了Go語言中new()函數(shù)的相關知識以及具體用法,文中的示例代碼講解詳細,具有一定的學習價值,感興趣的小伙伴可以了解一下
    2023-05-05
  • Go語言面向對象中的多態(tài)你學會了嗎

    Go語言面向對象中的多態(tài)你學會了嗎

    面向對象中的多態(tài)(Polymorphism)是指一個對象可以具有多種不同的形態(tài)或表現(xiàn)方式,本文將通過一些簡單的示例為大家講解一下多態(tài)的實現(xiàn),需要的可以參考下
    2023-07-07

最新評論