"Two goroutines sending messages to the same channel result in a 10-fold increase in time consumption

Why is there such a significant difference in the time taken for sending and receiving data through a channel between two goroutines?

golang version 1.18
this is my code

package main

import (
	"log"
	"time"
)

type Message struct {
	msgID     int
	timeStamp int64
	timeTime  time.Time
	msgType   int
}

func main() {

	const buffer = 1000

	msgChan := make(chan *Message, buffer)
	timeSumType1 := time.Time{}
	timeSumType2 := time.Time{}

	go func() {

		for i := 1; i <= 100; i++ {
			time.Sleep(time.Millisecond)
			timeT1 := time.Now()
			msgChan <- &Message{msgID: i, msgType: 1}
			timeDiff := time.Now().Sub(timeT1)
			log.Println("type 1, id :", i, " <- timeDelta:", timeDiff)
			timeSumType1 = timeSumType1.Add(timeDiff)

		}

	}()

	go func() {

		for i := 1; i <= 100; i++ {
			time.Sleep(100 * time.Millisecond)
			timeT1 := time.Now()
			msgChan <- &Message{msgID: i, msgType: 2}
			timeDiff := time.Now().Sub(timeT1)
			log.Println("type 2, id :", i, " <- timeDelta:", timeDiff)
			timeSumType2 = timeSumType2.Add(timeDiff)
		}

	}()

	time.Sleep(time.Second * 20)

	log.Println("type 1, timeSum:", timeSumType1)
	log.Println("type 2, timeSum:", timeSumType2)
}

the second goroutine sleep 100ms,the first goroutine sleep 1ms,

the first goroutine handle the msg type: 1
the second goroutine handle the msg type: 2

this is log :
2024/08/13 15:07:48 type 1, id : 97 ← timeDelta: 375ns
2024/08/13 15:07:48 type 1, id : 98 ← timeDelta: 500ns
2024/08/13 15:07:48 type 1, id : 99 ← timeDelta: 458ns
2024/08/13 15:07:48 type 1, id : 100 ← timeDelta: 417ns

2024/08/13 15:07:48 type 2, id : 2 ← timeDelta: 2.958µs
2024/08/13 15:07:49 type 2, id : 3 ← timeDelta: 20.25µs
2024/08/13 15:07:49 type 2, id : 4 ← timeDelta: 12.583µs

2024/08/13 15:08:08 type 1, timeSum: 0001-01-01 00:00:00.000116749 +0000 UTC
2024/08/13 15:08:08 type 2, timeSum: 0001-01-01 00:00:00.001056743 +0000 UTC

But Why does the second goroutine take several times longer for sending operations compared to the first goroutine?

What internal factors cause this difference?

There are a lot of factors at work, but I think one strong factor could be which go routine is executed on which system thread aka CPU-core.
If tow go-routines are executed on the same thread, they can use some optimizations especially if accessing shared memory.
Since go-routines are arbitrarily assigned to OS-Threads, one explanation could be that your “fast” routine lands on the same Thread as the worker-routine which keeps executing the code and might get a speed boost, since the data is accessed by the same CPU-core.

Thank you for your reply. I further simplified the demo to directly address the issue,I remove the worker goroutines,we can focous on the sending operation,

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.