Skip to content

多线程场景下并没有比 pond 性能好 #26

@ziyht

Description

@ziyht
goos: darwin
goarch: arm64
pkg: github.com/ziyht/eden_go/ert
cpu: Apple M3 Ultra
BenchmarkGoPool
BenchmarkGoPool-30                      10000000              1165 ns/op               0 B/op          0 allocs/op
BenchmarkGoPoolWithSpinLock
BenchmarkGoPoolWithSpinLock-30          10000000              1176 ns/op               0 B/op          0 allocs/op
BenchmarkGoroutines
BenchmarkGoroutines-30                  10000000               442.9 ns/op           143 B/op          3 allocs/op
BenchmarkPond
BenchmarkPond-30                        10000000              1008 ns/op               0 B/op          0 allocs/op
BenchmarkAnts
BenchmarkAnts-30                        10000000              1447 ns/op               0 B/op          0 allocs/op
PASS
package ert

import (
	"math"
	"sync"
	"testing"
	"time"

	"github.com/alitto/pond"
	"github.com/daniel-hutao/spinlock"
	"github.com/devchat-ai/gopool"
	"github.com/stretchr/testify/assert"
	"github.com/panjf2000/ants/v2"
)

const (
	PoolSize = 1e4
)

// go test -benchmem -run=^$ -bench=. github.com/ziyht/eden_go/ert -v -benchtime=1000000x -cpu=10

func BenchmarkGoPool(b *testing.B) {
	pool := gopool.NewGoPool(PoolSize)
	defer pool.Release()

	taskFunc := func() (interface{}, error) {
		time.Sleep(10 * time.Millisecond)
		return nil, nil
	}

	b.ResetTimer()
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
				pool.AddTask(taskFunc)
		}
	})
	pool.Wait()
	b.StopTimer()
}

func BenchmarkGoPoolWithSpinLock(b *testing.B) {
	pool := gopool.NewGoPool(PoolSize, gopool.WithLock(new(spinlock.SpinLock)))
	defer pool.Release()

	taskFunc := func() (interface{}, error) {
		time.Sleep(10 * time.Millisecond)
		return nil, nil
	}

	b.ResetTimer()
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
				pool.AddTask(taskFunc)
		}
	})
	pool.Wait()
	b.StopTimer()
}

func BenchmarkGoroutines(b *testing.B) {
	b.ResetTimer()
	b.RunParallel(func(pb *testing.PB) {
		var localWg sync.WaitGroup

		for pb.Next() {
			localWg.Add(1)
			go func() (interface{}, error) {
				time.Sleep(10 * time.Millisecond)
				localWg.Done()
				return nil, nil
			}()
		}
		localWg.Wait()
	})
}

func BenchmarkPond(b *testing.B) {
	pool := pond.New(PoolSize, 0, pond.MinWorkers(PoolSize))

	taskFunc := func() {
		time.Sleep(10 * time.Millisecond)
	}

	b.ResetTimer()
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
				pool.Submit(taskFunc)
		}
	})
	pool.StopAndWait()
	b.StopTimer()
}

func BenchmarkAnts(b *testing.B) {
	pool, _ := ants.NewPool(PoolSize, 
		ants.WithMaxBlockingTasks(math.MaxInt32),
		// ants.WithNonblocking(true),
		ants.WithPreAlloc(true),
	)

	errs := 0

	b.ResetTimer()
	b.RunParallel(func(pb *testing.PB) {
		var localWg sync.WaitGroup

		localTaskFunc := func() {
			time.Sleep(10 * time.Millisecond)
			localWg.Done()
		}

		for pb.Next() {
			localWg.Add(1)
			err := pool.Submit(localTaskFunc)
			if err != nil {
				localWg.Done()
				errs++
			}
		}
		localWg.Wait()
	})

	assert.Equal(b, 0, errs)

	pool.Release()

	b.StopTimer()
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions