为什么有时候传值比转指针更快|青训营文章

191 阅读2分钟

本质是go语言逃逸分析,传指针内存一定分配在堆上,传值大概率在栈上,而栈比堆效率更高,原因如下:

什么是堆内存和栈内存?

根据内存管理(分配和回收)方式的不同,可以将内存分为 堆内存栈内存

那么他们有什么区别呢?

堆内存:由内存分配器和垃圾收集器负责回收

栈内存:由编译器自动进行分配和释放

一个程序运行过程中,也许会有多个栈内存,但肯定只会有一个堆内存。

每个栈内存都是由线程或者协程独立占有,因此从栈中分配内存不需要加锁,并且栈内存在函数结束后会自动回收,性能相对堆内存好要高。

而堆内存呢?由于多个线程或者协程都有可能同时从堆中申请内存,因此在堆中申请内存需要加锁,避免造成冲突,并且堆内存在函数结束后,需要 GC (垃圾回收)的介入参与,如果有大量的 GC 操作,将会吏程序性能下降得历害。传值比转指针更快的原因通常是因为传值涉及的数据量较小,而且避免了指针引用的间接性操作。以下是一些可能的原因:

  1. 数据量小:当要传递的数据量很小时,将数据直接复制到函数的参数中比通过指针传递引用更快。这是因为复制数据的开销相对较小,而指针传递需要额外的间接寻址和内存访问操作。
  2. 缓存友好性:传值可以提高缓存的利用效率。当数据传递给函数时,如果数据被复制到了函数的栈帧中,那么这些数据就在紧邻的内存位置上,可以更好地利用CPU缓存,减少缓存缺失的频率。
  3. 数据不可变性:如果数据在函数内部不会被修改,传值是安全的。这样可以避免使用指针传递时的额外检查和保护措施,进一步提高性能。

需要注意的是,对于大型数据结构或需要在函数内部修改的情况,传递指针通常更有效率。指针传递只需要复制一个指针的大小,而不是整个数据结构的大小。此外,通过指针传递引用可以避免数据的复制,节省了内存和处理时间。因此,在选择传值还是传递指针时,需要综合考虑数据量、数据是否可变以及性能需求。