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

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

當需要更多控制或處理非 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)換過程的更細粒度控制,包括 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
}

以下是對其核心部分的詳細解讀,將會突出了其性能優(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 標準庫對性能的深刻理解和關(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的方法與源碼的詳細內(nèi)容,更多關(guān)于GO中int轉(zhuǎn)換string的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go工具鏈之go tool fix用法詳解

    Go工具鏈之go tool fix用法詳解

    go tool fix 是 Go 工具鏈中的一個命令,作用是把指定 Go 程序代碼包中的的所有舊版本代碼修正為新版本的代碼,本文將簡單介紹一下go tool fix的使用方法,感興趣的小伙伴可以參考閱讀下
    2023-07-07
  • Go語言使用讀寫OPC詳解

    Go語言使用讀寫OPC詳解

    這篇文章主要介紹了Go語言使用讀寫OPC詳解,圖文講解的很清晰,有感興趣的同學(xué)可以學(xué)習(xí)下
    2021-03-03
  • K8s部署發(fā)布Golang應(yīng)用程序的實現(xiàn)方法

    K8s部署發(fā)布Golang應(yīng)用程序的實現(xiàn)方法

    本文主要介紹了K8s部署發(fā)布Golang應(yīng)用程序的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • 淺談Golang 切片(slice)擴容機制的原理

    淺談Golang 切片(slice)擴容機制的原理

    我們知道 Golang 切片在容量不足的情況下會進行擴容,擴容的原理是怎樣的呢,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • 深入理解Go語言對象池

    深入理解Go語言對象池

    對象池是一種在編程中用于優(yōu)化資源管理的技術(shù),本文主要介紹了深入理解Go語言對象池,對象池通常通過sync.Pool包或自定義數(shù)據(jù)結(jié)構(gòu)實現(xiàn),下面就來介紹一下
    2024-01-01
  • 使用Go語言實現(xiàn)接口繼承的方式

    使用Go語言實現(xiàn)接口繼承的方式

    在Go語言中,接口(interface)是一種定義方法集合的類型,它并不包含方法的具體實現(xiàn),只是規(guī)定實現(xiàn)該接口的類型必須提供這些方法的實現(xiàn),下面我將通過示例代碼來詳細解釋如何使用Go語言實現(xiàn)接口組合,以及為什么這種方式可以看作是實現(xiàn)接口繼承的一種方式
    2024-05-05
  • go語言中fallthrough的用法說明

    go語言中fallthrough的用法說明

    這篇文章主要介紹了go語言中fallthrough的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • Golang使用panic控制程序錯誤流程

    Golang使用panic控制程序錯誤流程

    這篇文章主要介紹了Golang使用panic控制程序錯誤流程,Golang panic異常處理機制中的一種流程控制方式,用于中斷程序流程并觸發(fā)異常處理
    2023-04-04
  • Go語言空白表示符_的實例用法

    Go語言空白表示符_的實例用法

    在本篇內(nèi)容里小編給大家整理的是一篇關(guān)于Go語言空白表示符_的實例用法,有興趣的朋友們可以學(xué)習(xí)參考下。
    2021-07-07
  • Golang在Window環(huán)境使用Imagick7的過程

    Golang在Window環(huán)境使用Imagick7的過程

    這篇文章主要介紹了Golang在Window環(huán)境使用Imagick7的過程,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2023-11-11

最新評論