MST

星途 面试题库

面试题:Go语言中for循环的常见优化方式

在Go语言中,写一个for循环遍历一个包含100万个整数的切片,计算所有元素的和。要求从性能优化角度给出至少两种优化方式,并解释优化原理。
22.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

import (
    "fmt"
)

func sum1(nums []int) int {
    sum := 0
    for _, num := range nums {
        sum += num
    }
    return sum
}

func sum2(nums []int) int {
    sum := 0
    length := len(nums)
    for i := 0; i < length; i++ {
        sum += nums[i]
    }
    return sum
}

func sum3(nums []int) int {
    const numWorkers = 4
    var sum int
    chunkSize := (len(nums) + numWorkers - 1) / numWorkers
    var results = make([]int, numWorkers)
    var workerFinished = make(chan bool, numWorkers)

    for i := 0; i < numWorkers; i++ {
        start := i * chunkSize
        end := (i + 1) * chunkSize
        if i == numWorkers - 1 {
            end = len(nums)
        }
        go func(workerIndex int) {
            for j := start; j < end; j++ {
                results[workerIndex] += nums[j]
            }
            workerFinished <- true
        }(i)
    }

    for i := 0; i < numWorkers; i++ {
        <-workerFinished
    }
    close(workerFinished)

    for _, res := range results {
        sum += res
    }
    return sum
}

优化方式一:避免每次循环获取切片长度

  1. 优化前
for _, num := range nums {
    sum += num
}

在使用 range 遍历切片时,每次迭代都可能隐式地获取切片的长度。虽然Go编译器会对此进行一定的优化,但显式获取长度并在循环外部保存可以减少这种开销。 2. 优化后

length := len(nums)
for i := 0; i < length; i++ {
    sum += nums[i]
}

原理:减少了每次循环时获取切片长度的开销,因为 len 函数在每次循环中不再重复调用,提高了循环执行效率。

优化方式二:并行计算

  1. 优化实现: 上述代码中的 sum3 函数将切片分成多个部分,使用多个goroutine并行计算每个部分的和,最后将各个部分的和累加起来。
  2. 原理:利用多核CPU的并行计算能力,提高计算效率。通过将大切片分成小的块,每个goroutine独立计算一块的和,最后合并结果,减少了总的计算时间。但需要注意的是,并行计算会引入额外的调度和通信开销,所以切片数据量较小时,并行计算可能反而会降低效率。