我有一個變量(但組合大小有上限)需要傳遞給C的GoStrings數量,我想盡可能便宜地做到這一點。我將多次執行此操作(因此可以考慮將重用的預分配緩沖區視為零成本)。我最初的方法是循環遍歷 GoStrings,將每個 GoString 轉換為 CString 并將其推送到 C。for _, str := range mystrings { cstr := C.CString(str) defer C.free(unsafe.Pointer(cstr)) C.push_str(pushStrFn, cstr)}當然,由于 以及 N 個 CGo 調用,這正在執行 N 堆分配 - 所有這些都不便宜。C.CString接下來是使用在開始時分配的時間在Go中構建一個大字符串,然后在單個CGo調用中將其傳遞給C,并帶有一些長度信息。這是一個 CString 調用和一個 CGo 調用 - 這是一個實質性的改進。strings.Builderbuilder.Reset()for _, str := range mystrings { builder.WriteString(str)}C.push_strs(pushStrsFn, C.CString(builder.String()))但是這種方法仍在執行不必要的復制!理想情況下,我想預先分配一大塊內存,我可以將其傳遞給C,然后只需將字符串直接復制到C中,而無需使用大型GoString中介。我能夠提前預先分配一個大數組,并迭代GoStrings中的字符,一次復制一個。這避免了中間復制,但比專用的字符串復制函數(如構建器的函數)慢得多。cCharArray := C.malloc(C.size_t(MAX_SIZE) * C.size_t(unsafe.Sizeof(uintptr(0))))goCharArray := (*[1<<30 - 1]C.char)(cCharArray)for _, str := range mystrings { for i, c := range str { goCharArray[offset+i] = C.char(c) }}C.push_charArray(pushCharArrayFn, (*C.char)(cCharArray))有沒有一種更快的方法來做到這一點,我錯過了?我是否可以以某種方式將 C 緩沖區饋送到 ,或者使用字符串復制函數直接提供給 C 緩沖區?strings.Builder
2 回答

繁星淼淼
TA貢獻1775條經驗 獲得超11個贊
你試過嗎,或者這個包裝器在它上面?https://github.com/chai2010/cgo/blob/master/char.go#L61 .如果這速度不快,您可以嘗試使用不安全將指向 Go 字符串的指針轉換為 CString 指針。C.strncpy

胡說叔叔
TA貢獻1804條經驗 獲得超8個贊
使用不安全的包從 C 分配的緩沖區中創建字節片。
然后,您可以直接復制到該切片中,也可以將其作為零長度的復切片粘貼到字節中。緩沖并使用寫字符串。您必須小心不要超過原始容量,否則緩沖區會將數據復制到新的后備緩沖區。
- 2 回答
- 0 關注
- 132 瀏覽
添加回答
舉報
0/150
提交
取消