这篇主要是纠正上一篇的补坑法….
第一个坑
在上一篇文章我修改错误时是这么来整的
1 | proChan := make(chan AreaList,len(prolist)) |
但其实是可以不用 channel
的 , 具体方法如下:
1 | for _, pro := range prolist { |
就完事了…. 所以说自大是真的不好,没个几年经验还是不要轻易的去帮忙修代码。
第二个坑
当对于处理少量数据的时候,使用goroutine
反而会拖慢系统的速度,因为goroutine
的使用是需要额外开销的。
举个例子:
1 | func ListBroken(city int) ([]ClientListModel, int, error) { |
这是一段业务代码 , 如你所见…非常臃肿,在获取数据时的时候已经没了 5~7ms了 ,整段代码在测试环境跑完需要11ms左右,这还是因为需要验证的数据只有两条,生产环境下跑完这一段似乎需要整整300ms左右,所以我着手尝试改造…
1 | clientSocket := make([]ClientListModel, 0) |
这是一次失败的尝试 ,在改造中,我把原来的 for range
改成了 gjson
库自带的 ForEach()
。让我们看看这段代码实现了些啥…
1 | // ForEach iterates through values. |
这次改造后,反而比原先的实现多了2ms左右时间开销。
总之就是为了兼容性多了很多对当前环境不必要的实现 ,多了一笔可观的消耗。虽然写的时候似乎比for range
美观(其实也没美观多少),但其实是非常的得不偿失的。而且其实在使用.Array()
之后, 我们得到的是一个slice
对象,而不是map
对象 ,所以我们其实可以使用for i:=0;i<len(slice);i++
来实现遍历,这样子虽然看着丑,但是性能实现其实比使用 for range
高整整一倍。for range
比常规循环的具体原因是,它在实现遍历的同时,还需要对循环元素进行拷贝,而slice[i]
是直接指针索引,性能肯定比拷贝快得多(参考源 )。
【修正 : for range
可以直接只把index
索引出来。 】
然后我把代码修改为:
1 | clientSocket := make([]ClientListModel, 0) |
这样子,就比原先的实现还少了2ms , 这还是使用了gorouite
的情况下。