/* 题解比我简洁一点,学习 */ funcexclusiveTime_ans(n int, logs []string) []int { ans := make([]int, n) type pair struct{ idx, timestamp int } st := []pair{} for _, log := range logs { sp := strings.Split(log, ":") idx, _ := strconv.Atoi(sp[0]) timestamp, _ := strconv.Atoi(sp[2]) if sp[1][0] == 's' { iflen(st) > 0 { ans[st[len(st)-1].idx] += timestamp - st[len(st)-1].timestamp st[len(st)-1].timestamp = timestamp } st = append(st, pair{idx, timestamp}) } else { p := st[len(st)-1] st = st[:len(st)-1] ans[p.idx] += timestamp - p.timestamp + 1 iflen(st) > 0 { st[len(st)-1].timestamp = timestamp + 1 } } } return ans }
Review
concurrence in go的英文原文的最后一节 work stealing
All things considered, stealing continuations are considered to be theoretically supe‐ rior to stealing tasks, and therefore it is best to queue the continuation and not the goroutine
综合考虑所有因素,偷接被认为在理论上优于偷接任务,因此最好是排队继续而不是goroutine
So why don’t all work-stealing algorithms implement continuation stealing? Well, continuation stealing usually requires support from the compiler. Luckily, Go has its own compiler, and continuation stealing is how Go’s work-stealing algorithm is implemented. Languages that don’t have this luxury usually implement task, or socalled “child, ” stealing as a library.
type APIConnection struct { networkLimit, diskLimit, apiLimit RateLimiter }
func(a *APIConnection)ReadFile(ctx context.Context)error { err := MultiLimiter(a.apiLimit, a.diskLimit).Wait(ctx) //4 if err != nil { return err } // Pretend we do work here returnnil }