Golang使用fmt.PrintLn旋转大数字数组时出现卡顿问题
Golang使用fmt.PrintLn旋转大数字数组时出现卡顿问题 -2
我是Go语言的新手,为了练习,我正在尝试解决一个需要将数组旋转一定次数的问题。但是我的代码能够打印出包含3万个元素的结果数组,而当数组更大(8.9万个元素)时,打印就会卡住。请帮我找到解决方案。我的代码如下:
package main
import (
"fmt"
"math"
"strings"
)
func rotate(arr []string,count,elem int) string {
if count > elem {
count = int(math.Mod(float64(count), float64(elem)))
}
return strings.Join(arr[len(arr)-count:]," ")+" "+strings.Join(arr[:len(arr)-count]," ")
}
func main() {
var tc,elem,rot int
var d string
fmt.Scanln(&tc)
for i := 0; i < tc; i++ {
fmt.Scan(&elem,&rot)
myrr:=[]string{}
for j:=0;j<elem;j++{
fmt.Scan(&d)
myrr=append(myrr,d)
}
fmt.Println(strings.Trim(rotate(myrr,rot,elem)," "))
}
}
更多关于Golang使用fmt.PrintLn旋转大数字数组时出现卡顿问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
你好,
有什么问题吗?我无法复现这个问题。 我可以打印一个包含98k个元素的数组/切片。
// 创建98k大小的切片
a := make([]string, 98000)
// 用示例数据填充 `a`
for i := range a {
a[i] = strconv.Itoa(i)
}
// 打印 `a`
fmt.Println(a)
更多关于Golang使用fmt.PrintLn旋转大数字数组时出现卡顿问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
是的,你发布的那个编译器链接无法编译我的程序。它可能有一些保护措施以避免性能问题。
不过,我找到的其他在线编译器工作正常:
GDB online Debugger | Code, Compile, Run, Debug online C, C++
Online GDB 是一个支持 C/C++ 的在线集成开发环境,包含编译器和调试器。你可以编写代码、编译、运行、调试并分享代码片段。
你好 @gucio321,
感谢你的回复。
我已经在我的本地环境中尝试了你的代码,代码运行正常。但是,每当我尝试在任何在线编译器上运行时,例如 https://www.tutorialspoint.com/execute_golang_online.php,我发现它会卡住。我在多个网站上尝试过,都观察到了同样的情况。同时我还观察到,它无法扫描一个包含 98k 个输入的样本。请从这个链接下载示例文本文件:https://drive.google.com/file/d/1YzVJ_zWln10KXe3NniOJvaWwYQBIyMon/view?usp=sharing 这个输入文件在使用 Python 扫描 89k 个数字时工作正常,但在使用 Go 时会卡住。
如果你能用提供的输入文件运行我的代码,请告诉我。这里第一行表示“测试用例的数量”,第二行表示两个元素:一个是数组中要存储的元素数量,第二个是数组的旋转次数,第三行表示所有元素。
此致, Amit
问题出在fmt.Println打印大量数据时的性能瓶颈。对于8.9万个元素,每个元素都需要格式化为字符串并输出,这会导致明显的延迟。以下是优化方案:
package main
import (
"bufio"
"io"
"math"
"os"
"strings"
)
func rotate(arr []string, count, elem int) string {
if count > elem {
count = int(math.Mod(float64(count), float64(elem)))
}
// 预分配结果字符串的缓冲区
var result strings.Builder
result.Grow(len(arr)*2) // 预估空间:每个元素+空格
// 构建旋转后的字符串
result.WriteString(strings.Join(arr[len(arr)-count:], " "))
result.WriteString(" ")
result.WriteString(strings.Join(arr[:len(arr)-count], " "))
return result.String()
}
func main() {
reader := bufio.NewReader(os.Stdin)
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
var tc, elem, rot int
// 使用Fscan提高读取效率
_, _ = fmt.Fscan(reader, &tc)
for i := 0; i < tc; i++ {
_, _ = fmt.Fscan(reader, &elem, &rot)
myrr := make([]string, 0, elem)
var d string
for j := 0; j < elem; j++ {
_, _ = fmt.Fscan(reader, &d)
myrr = append(myrr, d)
}
// 直接写入缓冲输出,避免fmt.Println的性能开销
result := strings.Trim(rotate(myrr, rot, elem), " ")
_, _ = io.WriteString(writer, result)
_, _ = writer.WriteString("\n")
}
}
关键优化点:
- 使用
bufio.Writer缓冲输出,减少系统调用次数 - 使用
strings.Builder预分配字符串构建缓冲区 - 用
io.WriteString替代fmt.Println避免格式化开销 - 使用
bufio.Reader提高输入读取效率
对于3万个元素,原代码可能勉强运行,但8.9万个元素时fmt.Println的格式化开销会显著增加。缓冲写入直接操作字节,性能更高。

