最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

GO中高效的將int轉(zhuǎn)換為string的方法與源碼

 更新時間:2024年01月22日 08:46:45   作者:波羅學(xué)  
本文將從逐步介紹幾種在?Go?中將?int?轉(zhuǎn)換為?string?的常見方法,并重點剖析這幾種方法在性能上的特點,另外,還會重點介紹?FormatInt?高效的算法實現(xiàn),需要的朋友可以參考下

Go 語言 中,將整數(shù)(int)轉(zhuǎn)換為字符串(string)是一項常見的操作。

本文將從逐步介紹幾種在 Go 中將 int 轉(zhuǎn)換為 string 的常見方法,并重點剖析這幾種方法在性能上的特點。另外,還會重點介紹 FormatInt 高效的算法實現(xiàn)。

使用 strconv.Itoa

最直接且常用的方法是使用 strconv 包中的 Itoa 函數(shù)。Itoa 是 “Integer to ASCII” 的簡寫,它提供了一種快速且簡潔的方式實現(xiàn)整數(shù)到字符串之間的轉(zhuǎn)換。

示例代碼如下:

package main

import (
    "strconv"
    "fmt"
)

func main() {
    i := 123
    s := strconv.Itoa(i)
    fmt.Println(s)
}

strconv.Itoa 是通過直接將整數(shù)轉(zhuǎn)換為其 ASCII 字符串表示形式。這個過程中盡量減少了額外的內(nèi)存分配,沒有復(fù)雜邏輯。

使用 fmt.Sprintf

另一種方法是,使用 fmt 包的 Sprintf 函數(shù)。這個方法在功能上更為強大和靈活,因為它能處理各種類型并按照指定的格式輸出。

示例代碼如下:

package main

import (
    "fmt"
)

func main() {
    i := 123
    s := fmt.Sprintf("%d", i)
    fmt.Println(s)
}

雖然 fmt.Sprintf 在功能上非常強大,但它的性能通常不如 strconv.Itoa

為什么呢?

因為 fmt.Sprintf 內(nèi)部使用了反射(reflection)確定輸入值類型,并且在處理過程中涉及到更多的字符串拼接和內(nèi)存分配。

使用 strconv.FormatInt

當(dāng)需要更多控制或處理非 int 類型的整數(shù)(如 int64)時,可以使用 strconv 包的 FormatInt 函數(shù)。

package main

import (
    "strconv"
    "fmt"
)

func main() {
    var i int64 = 123
    s := strconv.FormatInt(i, 10)  // 10 表示十進制
    fmt.Println(s)
}

strconv.FormatInt 提供了對整數(shù)轉(zhuǎn)換過程的更細(xì)粒度控制,包括 base 的選擇(例如,十進制、十六進制等)。

strconv.Itoa 類似,FormatInt 在性能上也非常可觀,而且 FormatInt 提供了既靈活又高效的解決方案。

如果我們查看 strconv.Itoa 源碼,會發(fā)現(xiàn) strconv.Itoa 其實是 strconv.FormatInt 的一個特殊情況。

// Itoa is shorthand for FormatInt(int64(i), 10).
func Itoa(i int) string {
    return FormatInt(int64(i), 10)
}

現(xiàn)在 int 轉(zhuǎn) string 的高性能源碼剖析,就變成了重點剖析 FormatInt。

FormatInt 深入剖析

基于 Go 1.21 版本的 itoa.go 源碼,我們可以深入理解 strconv 包中整數(shù)到字符串轉(zhuǎn)換函數(shù)的高效實現(xiàn)。

func FormatInt(i int64, base int) string {
	if fastSmalls && 0 <= i && i < nSmalls && base == 10 {
		return small(int(i)) // 100 以內(nèi)的十進制小整數(shù),使用 small 函數(shù)轉(zhuǎn)化
	}
  	_, s := formatBits(nil, uint64(i), base, i < 0, false) // 其他情況使用 formatBits
	return s
}

以下是對其核心部分的詳細(xì)解讀,將會突出了其性能優(yōu)化的關(guān)鍵方面,結(jié)合具體的源碼實現(xiàn)說明。

1. 快速路徑處理小整數(shù)

對于常見的小整數(shù),strconv 包提供了一個快速路徑,small 函數(shù),直接返回預(yù)先計算好的字符串,避免了運行時的計算開銷。

func small(i int) string {
	if i < 10 {
		return digits[i : i+1]
	}
	return smallsString[i*2 : i*2+2]
}

對于小于 100 的十進制整數(shù),采用這個快速實現(xiàn)方案,或許這也是整數(shù)轉(zhuǎn)字符串的最常見使用場景吧。

small 函數(shù)通過索引到 smallsStringdigits 獲取小整數(shù)的字符串表示,這個過程非常快速。 digitssmallsString 的值,如下所示:

const smallsString = "00010203040506070809" +
	"10111213141516171819" +
	"20212223242526272829" +
	"30313233343536373839" +
	"40414243444546474849" +
	"50515253545556575859" +
	"60616263646566676869" +
	"70717273747576777879" +
	"80818283848586878889" +
	"90919293949596979899"

const digits = "0123456789abcdefghijklmnopqrstuvwxyz"

它們也就是十進制 0-99 與對應(yīng)字符串的映射。

2. formatBits 函數(shù)的高效實現(xiàn)

FormatInt 最復(fù)雜的部分是 formatBits 函數(shù),它是整數(shù)到字符串轉(zhuǎn)換的核心,它針對不同的基數(shù)進行了優(yōu)化。

10進制轉(zhuǎn)換的優(yōu)化

對于10進制轉(zhuǎn)換,formatBits 使用了基于除法和取余的算法,并通過 smallsString 加速兩位數(shù)的字符串獲取。

if base == 10 {
	// ... (32位系統(tǒng)的優(yōu)化)
	us := uint(u)
	for us >= 100 {
		is := us % 100 * 2
		us /= 100
		i -= 2
		a[i+1] = smallsString[is+1]
		a[i+0] = smallsString[is+0]
	}
	// ... (處理剩余的數(shù)字)
}
  • 對于 32 位系統(tǒng),使用32位操作處理較大的數(shù)字,減少 64 位除法的開銷。
  • 每次處理兩位數(shù)字,直接從 smallsString 獲取對應(yīng)的字符,避免了單獨轉(zhuǎn)換每一位的開銷。

2的冪基數(shù)的優(yōu)化

對于基數(shù)是2的冪的情況,formatBits 使用了位操作來優(yōu)化轉(zhuǎn)換。

} else if isPowerOfTwo(base) {
	shift := uint(bits.TrailingZeros(uint(base))) & 7
	b := uint64(base)
	m := uint(base) - 1 // == 1<<shift - 1
	for u >= b {
		i--
		a[i] = digits[uint(u)&m]
		u >>= shift
	}
	// u < base
	i--
	a[i] = digits[uint(u)]
}
  • 位操作是直接在二進制上進行,比除法和取余操作更快。
  • 利用 2 的冪基數(shù)的特性,通過移位和掩碼操作獲取數(shù)字的各個位。

通用情況的處理

對于其他基數(shù),formatBits 使用了通用的算法,但仍然盡量減少了除法和取余操作的使用。

} else {
	// general case
	b := uint64(base)
	for u >= b {
		i--
		// Avoid using r = a%b in addition to q = a/b
		// since 64bit division and modulo operations
		// are calculated by runtime functions on 32bit machines.
		q := u / b
		a[i] = digits[uint(u-q*b)]
		u = q
}

我覺得最核心的算法就是利用移位和特殊路徑預(yù)置映射關(guān)系。另外,由于算法足夠優(yōu)秀,還避免了一些不必要內(nèi)存分配。

結(jié)論

將 int 轉(zhuǎn)化為 string 是一個非常常見的需求。Go 語言的 strconv 包中的 int 到 string 的轉(zhuǎn)換函數(shù)展示了 Go 標(biāo)準(zhǔn)庫對性能的深刻理解和關(guān)注。

通過快速處理小整數(shù)、優(yōu)化的 10 進制轉(zhuǎn)換算法、以及2^n 基數(shù)的特別處理,這些函數(shù)能夠提供高效且穩(wěn)定的性能。這些優(yōu)化確保了即使在大量數(shù)據(jù)或在性能敏感的場景中,strconv 包的函數(shù)也能提供出色的性能

以上就是GO中高效的將int轉(zhuǎn)換string的方法與源碼的詳細(xì)內(nèi)容,更多關(guān)于GO中int轉(zhuǎn)換string的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go環(huán)境變量配置,及GOROOT、GOPATH的區(qū)別小結(jié)

    Go環(huán)境變量配置,及GOROOT、GOPATH的區(qū)別小結(jié)

    本文主要介紹了Go環(huán)境變量配置,及GOROOT、GOPATH的區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-09-09
  • gin框架Context如何獲取Get?Query?Param函數(shù)數(shù)據(jù)

    gin框架Context如何獲取Get?Query?Param函數(shù)數(shù)據(jù)

    這篇文章主要為大家介紹了gin框架Context?Get?Query?Param函數(shù)獲取數(shù)據(jù),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • Golang中的閉包(Closures)詳解

    Golang中的閉包(Closures)詳解

    在?Golang?中,閉包是一個引用了作用域之外的變量的函數(shù),Golang?中的匿名函數(shù)也被稱為閉包,閉包可以被認(rèn)為是一種特殊類型的匿名函數(shù),所以本文就給大家詳細(xì)的介紹一下Golang的閉包到底是什么,感興趣的小伙伴跟著小編一起來看看吧
    2023-07-07
  • go各種import的使用方法講解

    go各種import的使用方法講解

    今天小編就為大家分享一篇關(guān)于go各種import的使用方法講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • GO語言中g(shù)ox交叉編譯的實現(xiàn)

    GO語言中g(shù)ox交叉編譯的實現(xiàn)

    本文主要介紹了GO語言中g(shù)ox交叉編譯的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-11-11
  • go內(nèi)置函數(shù)copy()的具體使用

    go內(nèi)置函數(shù)copy()的具體使用

    當(dāng)我們在Go語言中需要將一個切片的內(nèi)容復(fù)制到另一個切片時,可以使用內(nèi)置的copy()函數(shù),本文就介紹了go內(nèi)置函數(shù)copy()的具體使用,感興趣的可以了解一下
    2023-08-08
  • Go中的Context實現(xiàn)原理以及正確使用方式

    Go中的Context實現(xiàn)原理以及正確使用方式

    在 Go 語言中,Context 包是一種非常常用的工具,它被用來管理 goroutine 之間的通信和取消,本文將深入探討Context 包的基本原理,包括使用場景、原理和一些最佳實踐,感興趣的小伙伴跟著小編一起來看看吧
    2024-11-11
  • Go語言基礎(chǔ)go接口用法示例詳解

    Go語言基礎(chǔ)go接口用法示例詳解

    這篇文章主要為大家介紹了Go語言基礎(chǔ)關(guān)于go接口的用法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,在日升職加薪
    2021-11-11
  • Go?語言?net/http?包使用之HTTP?服務(wù)器、客戶端與中間件詳解

    Go?語言?net/http?包使用之HTTP?服務(wù)器、客戶端與中間件詳解

    Go 語言標(biāo)準(zhǔn)庫中的net/http包十分的優(yōu)秀,提供了非常完善的 HTTP 客戶端與服務(wù)端的實現(xiàn),僅通過幾行代碼就可以搭建一個非常簡單的 HTTP 服務(wù)器,本文給大家介紹Go語言net/http包使用之HTTP服務(wù)器、客戶端與中間件的操作,感興趣的朋友一起看看吧
    2025-05-05
  • golang中實現(xiàn)graphql請求的方法

    golang中實現(xiàn)graphql請求的方法

    這篇文章主要介紹了如何在golang中實現(xiàn)graphql請求,在本文中,我們介紹了如何使用gqlgen來構(gòu)建GraphQL服務(wù),需要的朋友可以參考下
    2023-04-04

最新評論

涡阳县| 伊宁县| 神农架林区| 澎湖县| 伊宁市| 梓潼县| 江源县| 石门县| 大田县| 富宁县| 津南区| 青海省| 德昌县| 宿州市| 永昌县| 汕尾市| 江阴市| 鹿邑县| 陕西省| 万荣县| 仁布县| 孟连| 武安市| 霍林郭勒市| 开鲁县| 公安县| 资兴市| 枣强县| 上蔡县| 吴旗县| 綦江县| 富宁县| 鄱阳县| 丰城市| 南京市| 河南省| 同德县| 徐州市| 绥中县| 台州市| 关岭|