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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions