github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/prepare/23_proto_actor/spawnbenchmark/main.go (about)

     1  package main
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"log"
     7  	"os"
     8  	"runtime"
     9  	"runtime/pprof"
    10  	"time"
    11  
    12  	"github.com/AsynkronIT/protoactor-go/actor"
    13  	"github.com/AsynkronIT/protoactor-go/mailbox"
    14  )
    15  
    16  type request struct {
    17  	num  int
    18  	size int
    19  	div  int
    20  }
    21  
    22  var (
    23  	props = actor.PropsFromProducer(newState).WithMailbox(mailbox.UnboundedLockfree())
    24  )
    25  
    26  type state struct {
    27  	sum     int
    28  	replies int
    29  	replyTo *actor.PID
    30  }
    31  
    32  func newState() actor.Actor {
    33  	return &state{}
    34  }
    35  
    36  func (s *state) Receive(ctx actor.Context) {
    37  	switch msg := ctx.Message().(type) {
    38  	case *request:
    39  		if msg.size == 1 {
    40  			ctx.Respond(msg.num)
    41  			return
    42  		}
    43  
    44  		s.replies = msg.div
    45  		s.replyTo = ctx.Sender()
    46  		for i := 0; i < msg.div; i++ {
    47  			child := ctx.Spawn(props)
    48  			ctx.Request(child, &request{
    49  				num:  msg.num + i*(msg.size/msg.div),
    50  				size: msg.size / msg.div,
    51  				div:  msg.div,
    52  			})
    53  		}
    54  	case int:
    55  		s.sum += msg
    56  		s.replies--
    57  		if s.replies == 0 {
    58  			ctx.Send(s.replyTo, s.sum)
    59  		}
    60  	}
    61  }
    62  
    63  var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
    64  var memprofile = flag.String("memprofile", "", "write mem profile to file")
    65  
    66  func main() {
    67  	flag.Parse()
    68  	if *cpuprofile != "" {
    69  		f, err := os.Create(*cpuprofile)
    70  		if err != nil {
    71  			log.Fatal(err)
    72  		}
    73  		pprof.StartCPUProfile(f)
    74  		defer pprof.StopCPUProfile()
    75  	}
    76  	runtime.GOMAXPROCS(runtime.NumCPU())
    77  	runtime.GC()
    78  
    79  	rootContext := actor.EmptyRootContext
    80  
    81  	start := time.Now()
    82  	pid := rootContext.Spawn(props)
    83  	res, _ := rootContext.RequestFuture(pid, &request{
    84  		num:  0,
    85  		size: 1000000,
    86  		div:  10,
    87  	}, 10*time.Second).Result()
    88  	result := res.(int)
    89  
    90  	took := time.Since(start)
    91  	fmt.Printf("Result: %d in %d ms.\n", result, took.Nanoseconds()/1e6)
    92  
    93  	if *memprofile != "" {
    94  		f, err := os.Create(*memprofile)
    95  		if err != nil {
    96  			log.Fatal(err)
    97  		}
    98  		pprof.WriteHeapProfile(f)
    99  		f.Close()
   100  		return
   101  	}
   102  }