成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

用位運算為你的程序加速

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

前言

最近在持續優化之前編寫的 JSON 解析庫 xjson,主要是兩個方面的優化。

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

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

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]]

本次優化之后便能直接輸出 JSON 字符串了:

圖片

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

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 ""
}
}

圖片

用位運算優化

第二個優化主要是提高了性能,查詢一個復雜 JSON 數據的時候性能提高了大約 ?16%.

# 優化前
BenchmarkDecode-12 90013 66905 ns/op 42512 B/op 1446 allocs/op
# 優化后
BenchmarkDecode-12 104746 59766 ns/op 37749 B/op 1141 allocs/op

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

圖片

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

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

圖片

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

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

首先以這兩個狀態為例:

StatusObjectKey   status = 0x0002
StatusColon status = 0x0004

他們分別對應的二進制數據為:

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

當我們對這兩個數據求 | 運算得到的數據是 0110:

A:0010
B:0100

C:0110

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

// 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 值,只要得出的數據大于 0 我們就能判斷一個數據是否在給定的集合中了。

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

同樣的優化在解析查詢語法時也有使用:

圖片

其他奇淫巧技

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

// 偶數
a & 1 == 0

// 奇數
a & 1 == 1

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

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

總結

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

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

相關代碼:https://github.com/crossoverJie/xjson

責任編輯:武曉燕 來源: crossoverJie
相關推薦

2020-03-25 10:44:16

位運算操作技巧

2022-05-18 16:06:15

位運算異或運算

2022-05-23 15:02:19

異或運算面試真題

2020-06-18 09:04:59

CC++程序

2013-03-25 09:41:20

PythonCython

2023-09-19 23:17:43

Python緩存

2012-05-05 08:52:14

iPhone

2014-04-21 16:24:33

Web啟動畫面

2021-02-21 06:36:57

運算技巧按位

2013-11-05 13:19:37

設計加速

2011-01-13 14:38:00

JavascriptCSSWeb

2020-07-23 14:15:42

Cython的Python代碼

2019-08-21 13:40:50

2021-09-23 14:44:24

程序員計算機開發

2011-07-15 17:05:14

2009-07-31 16:48:44

C#位運算

2021-10-11 19:01:47

CPU位運算JS

2021-10-11 09:41:20

React位運算技巧前端

2011-05-03 09:14:45

QtOvi商店Symbian

2009-10-29 13:16:15

ADO.NET應用程序
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 99精品国产一区二区三区 | 欧美久久一区二区 | 中文字幕亚洲一区 | 中文字幕一区二区三区在线观看 | 国产精品高潮呻吟久久av黑人 | 一区二区三区四区在线 | 伊人在线 | 午夜精品视频在线观看 | 在线观看一区 | 天天操天天舔 | 91在线精品秘密一区二区 | 欧美一级黄色免费看 | av网站免费 | 国产黄色在线观看 | 日韩av.com | 在线播放中文字幕 | 精品欧美一区二区精品久久久 | 91国内精品 | 四虎午夜剧场 | 亚洲成人综合在线 | av在线免费观看网址 | 在线观看国产视频 | 国产精品中文字幕在线播放 | 天天爽综合网 | 国产三级国产精品 | 99re视频在线免费观看 | 亚洲激情网站 | 丁香婷婷综合激情五月色 | 黄色av大片| 欧美久久一区二区三区 | 日韩一区二区黄色片 | 久久精品女人天堂av | 亚洲免费视频网址 | 亚洲一区 中文字幕 | 欧美国产日韩在线观看 | 亚洲精选一区 | 99热激情 | 日韩午夜影院 | 每日更新av | 亚洲日本视频 | 97av视频在线 |