亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

淺析Go語言中的緩沖區(qū)及其在fmt包中的應用

 更新時間:2024年01月31日 11:00:16   作者:沙蒿同學  
這篇文章主要為大家詳細介紹了Go語言中的緩沖區(qū)及其在fmt包中的應用的相關知識,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下

傳統(tǒng)的IO流程

在傳統(tǒng)的IO流程中,通常涉及以下幾個步驟:

  • 打開文件或建立網(wǎng)絡連接:首先,需要打開文件或建立網(wǎng)絡連接,以便進行讀取或?qū)懭氩僮鳌_@通常涉及到操作系統(tǒng)提供的系統(tǒng)調(diào)用,如opensocket等。
  • 讀取或?qū)懭霐?shù)據(jù):一旦文件或網(wǎng)絡連接打開,就可以進行數(shù)據(jù)的讀取或?qū)懭氩僮鳌Wx取操作將從文件或網(wǎng)絡連接中獲取數(shù)據(jù),而寫入操作將將數(shù)據(jù)寫入文件或發(fā)送到網(wǎng)絡連接中。這些操作通常涉及到系統(tǒng)調(diào)用,如readwrite。
  • 緩沖區(qū):為了提高IO性能,通常會使用緩沖區(qū)。緩沖區(qū)是一塊內(nèi)存區(qū)域,用于臨時存儲要讀取或?qū)懭氲臄?shù)據(jù)。數(shù)據(jù)首先被讀取到緩沖區(qū)中,然后從緩沖區(qū)中寫入到文件或網(wǎng)絡連接中,或者從緩沖區(qū)中讀取數(shù)據(jù)。
  • 關閉文件或網(wǎng)絡連接:當讀取或?qū)懭氩僮魍瓿珊?,需要關閉文件或網(wǎng)絡連接。這通常涉及到系統(tǒng)調(diào)用,如close。

在傳統(tǒng)的IO流程中,每次讀取或?qū)懭氩僮鞫紩婕暗较到y(tǒng)調(diào)用,這會導致較高的開銷。為了提高性能,通常會使用緩沖區(qū)來減少系統(tǒng)調(diào)用的次數(shù)。緩沖區(qū)可以一次讀取或?qū)懭攵鄠€數(shù)據(jù),從而減少了系統(tǒng)調(diào)用的開銷。

緩沖區(qū)

上面我們了解到緩沖區(qū)這個概念,那什么是緩沖區(qū)呢?

內(nèi)存緩沖區(qū)是計算機中的一種臨時存儲區(qū)域,用于暫時存儲數(shù)據(jù)。它通常用于提高數(shù)據(jù)讀寫的效率,減少對底層存儲設備的頻繁訪問。

緩沖區(qū)的主要目的是在數(shù)據(jù)的生產(chǎn)者和消費者之間起到一個中間層的作用。當數(shù)據(jù)被生產(chǎn)者生成時,它首先被寫入緩沖區(qū),而不是直接寫入到目標存儲設備。然后,消費者可以從緩沖區(qū)中讀取數(shù)據(jù)。

緩沖區(qū)的大小是有限的,一旦緩沖區(qū)被填滿,生產(chǎn)者必須等待消費者讀取數(shù)據(jù),以便為新的數(shù)據(jù)騰出空間。同樣,如果緩沖區(qū)為空,消費者必須等待生產(chǎn)者生成新的數(shù)據(jù)。

內(nèi)存緩沖區(qū)可以用于各種場景,比如:

  • 文件讀寫:在讀取或?qū)懭氪笪募r,可以使用內(nèi)存緩沖區(qū)來提高讀寫性能。數(shù)據(jù)首先被讀取到緩沖區(qū)中,然后批量地寫入或讀取到磁盤上的文件。
  • 網(wǎng)絡通信:在網(wǎng)絡通信中,數(shù)據(jù)通常需要經(jīng)過網(wǎng)絡協(xié)議的封裝和解析。使用內(nèi)存緩沖區(qū)可以將數(shù)據(jù)暫時存儲起來,以便進行協(xié)議處理和網(wǎng)絡傳輸。
  • 數(shù)據(jù)庫操作:在數(shù)據(jù)庫操作中,使用內(nèi)存緩沖區(qū)可以提高數(shù)據(jù)的讀寫性能。數(shù)據(jù)首先被寫入緩沖區(qū),然后批量地寫入到數(shù)據(jù)庫中,或者從緩沖區(qū)中讀取數(shù)據(jù)進行查詢。

需要注意的是,內(nèi)存緩沖區(qū)只是一個臨時存儲區(qū)域,數(shù)據(jù)在緩沖區(qū)中并不是持久化的。一旦程序結束或緩沖區(qū)被清空,緩沖區(qū)中的數(shù)據(jù)就會丟失。因此,在使用內(nèi)存緩沖區(qū)時需要確保數(shù)據(jù)的正確性和一致性。

go緩沖區(qū)

在Go語言中,緩沖區(qū)的大小是由創(chuàng)建緩沖區(qū)時指定的參數(shù)決定的。在標準庫中,可以使用bufio包提供的NewWriterSize函數(shù)創(chuàng)建一個指定大小的緩沖區(qū)。

默認情況下,bufio.Writer的緩沖區(qū)大小為4096字節(jié)(4KB),即調(diào)用bufio.NewWriter創(chuàng)建的緩沖區(qū)大小為4096字節(jié)。這是因為4096字節(jié)是一個常見的磁盤塊大小,對于大多數(shù)應用場景來說,這個大小已經(jīng)足夠了。

如果需要自定義緩沖區(qū)的大小,可以使用bufio.NewWriterSize函數(shù)來指定緩沖區(qū)的大小。例如,可以通過bufio.NewWriterSize(writer, 8192)來創(chuàng)建一個大小為8192字節(jié)(8KB)的緩沖區(qū)。

為什么

為什么go編程中要設置緩沖區(qū)呢?其實我們上面都有提到:設置緩沖區(qū)的一個主要目的就是為了減少頻繁的IO操作。

在進行IO操作時,例如讀取或?qū)懭胛募?,每次都直接操作底層的存儲設備(如磁盤或網(wǎng)絡)可能會導致性能下降。這是因為每次IO操作都需要進行系統(tǒng)調(diào)用,這涉及到內(nèi)核和用戶空間之間的上下文切換,以及硬件設備的訪問延遲。

通過使用緩沖區(qū),可以將數(shù)據(jù)暫時存儲在內(nèi)存中,而不是直接與底層存儲設備進行交互。這樣可以將多個小的IO操作合并為一個大的IO操作,從而減少了系統(tǒng)調(diào)用的次數(shù)。這種批量處理的方式通常比頻繁的小IO操作更高效。

此外,緩沖區(qū)還可以提供更好的數(shù)據(jù)傳輸效率。當數(shù)據(jù)被寫入緩沖區(qū)時,實際的IO操作可以被推遲到緩沖區(qū)被填滿或手動刷新緩沖區(qū)時才執(zhí)行。這樣可以減少IO操作的次數(shù),提高數(shù)據(jù)傳輸?shù)男省?/p>

go 緩沖區(qū)(Buffer)是分配在堆還是棧?

在Go語言中,緩沖區(qū)(Buffer)的申請是在堆上進行的。

Go語言中的??臻g是有限的,而且棧上的內(nèi)存分配和釋放是由編譯器自動管理的,無法手動控制。因此,較大的緩沖區(qū)無法放在棧上進行申請。

相反,Go語言中的堆空間是用于動態(tài)分配內(nèi)存的,可以手動控制內(nèi)存的申請和釋放。當我們使用make關鍵字創(chuàng)建一個切片或映射時,內(nèi)存就會在堆上進行動態(tài)分配。而bufio包中的緩沖區(qū)也是通過make函數(shù)在堆上進行申請的。

緩沖區(qū)的申請通常是在創(chuàng)建緩沖區(qū)時進行的,例如使用bufio.NewWriterbufio.NewWriterSize函數(shù)來創(chuàng)建一個緩沖區(qū)對象。這個過程會調(diào)用make函數(shù)來分配足夠大小的內(nèi)存,并返回一個指向該內(nèi)存的指針。

fmt打印

示例

fmt.Println("Hello, world!"),大家平時用得最多了,這不就是打印輸出到控制臺嘛

當執(zhí)行fmt.Println("Hello, world!")命令時,會調(diào)用fmt包內(nèi)的Println函數(shù)來打印輸出。

首先,Println函數(shù)會根據(jù)傳入的參數(shù)列表構建一個字符串,并將其傳遞給Fprintln函數(shù)。Fprintln函數(shù)是fmt包內(nèi)部的一個輔助函數(shù),它會將構建的字符串寫入到標準輸出(即控制臺)。

Fprintln函數(shù)內(nèi)部,它會調(diào)用newPrinter函數(shù)來創(chuàng)建一個pp(printer)對象。pp對象是printer結構體的實例,它包含了打印輸出的相關配置和狀態(tài)信息。

接下來,Fprintln函數(shù)會調(diào)用pp.print方法來實際執(zhí)行打印輸出的操作。在print方法中,它會根據(jù)配置的格式化選項,將構建的字符串寫入到pp.buf緩沖區(qū)中。

如果緩沖區(qū)已滿,或者遇到換行符(\n),print方法會調(diào)用pp.write方法將緩沖區(qū)的內(nèi)容寫入到標準輸出。write方法會使用os.Stdout作為目標,將緩沖區(qū)的內(nèi)容寫入到控制臺。

最后,Fprintln函數(shù)會調(diào)用pp.free方法來釋放pp對象占用的內(nèi)存,以及清空緩沖區(qū)。

總結起來,當執(zhí)行fmt.Println("Hello, world!")命令時,fmt包內(nèi)部會構建打印輸出的字符串,并將其寫入到標準輸出。這個過程涉及到字符串的構建、緩沖區(qū)的管理和標準輸出的寫入。通過使用printer結構體和相關方法,fmt包實現(xiàn)了方便的打印輸出功能。

源碼查看

// ...
func main() {
    fmt.Println("Hello, world!")
}

// fmt 包
// ...
func Println(a ...any) (n int, err error) {
	return Fprintln(os.Stdout, a...)
}
// ...
func Fprintln(w io.Writer, a ...any) (n int, err error) {
	p := newPrinter()
	p.doPrintln(a)
	n, err = w.Write(p.buf)
	p.free()
	return
}

當打印內(nèi)容很大怎么辦

當打印的內(nèi)容超出了緩沖區(qū)的大小時,fmt包會動態(tài)擴展緩沖區(qū)的大小,以容納更大的數(shù)據(jù),并完整地輸出到標準輸出。

在執(zhí)行打印操作時,fmt包會檢查緩沖區(qū)的剩余空間是否足夠容納當前要打印的內(nèi)容。如果空間不足,fmt包會自動擴展緩沖區(qū)的大小,通常是將緩沖區(qū)的大小翻倍。

例如,在默認情況下,fmt包的緩沖區(qū)大小為4KB。如果要打印的內(nèi)容超過了4KB,fmt包會自動將緩沖區(qū)擴展到8KB,以容納更多的數(shù)據(jù)。如果仍然不夠,會繼續(xù)擴展到16KB,以此類推,直到能夠容納所有的數(shù)據(jù)。

當緩沖區(qū)大小足夠容納要打印的內(nèi)容時,fmt包會將數(shù)據(jù)寫入緩沖區(qū)中。當緩沖區(qū)滿了或者遇到換行符(\n)時,fmt包會將緩沖區(qū)的內(nèi)容寫入到標準輸出,確保完整地輸出所有的數(shù)據(jù)。

也就是說我有一個8k的打印內(nèi)容,而緩沖區(qū)大小為4KB,那么在第一次寫入緩沖區(qū)后,緩沖區(qū)將被填滿。此時,fmt包會進行一次IO操作,將緩沖區(qū)的內(nèi)容寫入標準輸出。

由于緩沖區(qū)已滿,第二次寫入操作將觸發(fā)另一次IO操作,將剩余的內(nèi)容寫入標準輸出。

因此,在這種情況下,fmt包會進行兩次IO操作,將完整的8KB內(nèi)容寫入標準輸出。第一次是在緩沖區(qū)填滿后,第二次是在第二次寫入時。

到此這篇關于淺析Go語言中的緩沖區(qū)及其在fmt包中的應用的文章就介紹到這了,更多相關Go緩沖區(qū)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Go語言中的map擴容機制

    Go語言中的map擴容機制

    Go語言中的map是一種高效的數(shù)據(jù)結構,其擴容機制確保了在大數(shù)據(jù)量情況下的性能,本文介紹了包括擴容觸發(fā)條件、擴容過程和漸進式擴容,感興趣的可以了解一下
    2024-12-12
  • golang使用sync.singleflight解決熱點緩存穿透問題

    golang使用sync.singleflight解決熱點緩存穿透問題

    在go的sync包中,有一個singleflight包,里面有一個?singleflight.go文件,代碼加注釋,一共200行出頭,通過?singleflight可以很容易實現(xiàn)緩存和去重的效果,避免重復計算,接下來我們就給大家詳細介紹一下sync.singleflight如何解決熱點緩存穿透問題
    2023-07-07
  • 以go為例探究beyla從環(huán)境變量BEYLA_OPEN_PORT發(fā)現(xiàn)進程原理

    以go為例探究beyla從環(huán)境變量BEYLA_OPEN_PORT發(fā)現(xiàn)進程原理

    這篇文章主要為大家介紹了以golang進程為例,研究beyla從環(huán)境變量BEYLA_OPEN_PORT(即通過端口)發(fā)現(xiàn)進程的原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • 一文詳解golang延時任務的實現(xiàn)

    一文詳解golang延時任務的實現(xiàn)

    這篇文章主要為大家介紹了golang延時任務的實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • 深入理解Golang channel的應用

    深入理解Golang channel的應用

    channel是用于 goroutine 之間的同步、通信的數(shù)據(jù)結構。它為程序員提供了更高一層次的抽象,封裝了更多的功能,這樣并發(fā)編程變得更加容易和安全。本文通過示例為大家詳細介紹了channel的應用,需要的可以參考一下
    2022-10-10
  • 詳解Golang net/http包中的RoundTripper接口

    詳解Golang net/http包中的RoundTripper接口

    RoundTripper 是 net/http 包中的一個接口,定義了處理 HTTP 請求返回和響應的方法,是 http.Client 結構體中執(zhí)行 http 請求的核心部分,本文將詳細的給大家介紹Golang RoundTripper接口,需要的朋友可以參考下
    2023-09-09
  • Go模板template用法詳解

    Go模板template用法詳解

    這篇文章主要介紹了Go標準庫template模板用法詳解;包括GO模板注釋,作用域,語法,函數(shù)等知識,需要的朋友可以參考下
    2022-04-04
  • go切片和指針切片示例詳解

    go切片和指針切片示例詳解

    在Go語言中,切片(Slice)和指針的切片(即切片中每個元素都是指向某種數(shù)據(jù)類型的指針)是兩個不同的概念,它們各自具有特定的用途和優(yōu)勢,這篇文章主要介紹了go切片和指針切片,需要的朋友可以參考下
    2024-04-04
  • Golang map實踐及實現(xiàn)原理解析

    Golang map實踐及實現(xiàn)原理解析

    這篇文章主要介紹了Golang map實踐以及實現(xiàn)原理,Go 語言中,通過哈希查找表實現(xiàn) map,用鏈表法解決哈希沖突,本文結合實例代碼給大家介紹的非常詳細,需要的朋友參考下吧
    2022-06-06
  • Go每日一庫之quicktemplate的使用

    Go每日一庫之quicktemplate的使用

    quicktemplate快速、功能強大、易于使用的Go模板引擎。比html/模板快20倍,本文我們就詳細的介紹一下quicktemplate的具體使用,感興趣的可以了解一下
    2021-07-07

最新評論