-
-
Save rkmathi/e205d1c98f7f61ade76acc534480dad5 to your computer and use it in GitHub Desktop.
18:28
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(pprof) list calcStatus | |
Total: 1.42mins | |
ROUTINE ======================== main.calcStatus in /home/isucon/isucon7-final/webapp/go/src/app/game.go | |
440ms 1.15mins (flat, cum) 81.24% of Total | |
. . 441:} | |
. . 442: | |
. . 443:func calcStatus(currentTime int64, mItems map[int]mItem, addings []Adding, buyings []Buying) (*GameStatus, error) { | |
. . 444: var ( | |
. . 445: // 1ミリ秒に生産できる椅子の単位をミリ椅子とする | |
. 20ms 446: totalMilliIsu = big.NewInt(0) | |
. 10ms 447: totalPower = big.NewInt(0) | |
. . 448: | |
. 10ms 449: itemPower = map[int]*big.Int{} // ItemID => Power | |
. 10ms 450: itemPrice = map[int]*big.Int{} // ItemID => Price | |
. . 451: itemPrice1000 = map[int]*big.Int{} // ItemID => Price * 1000 | |
. . 452: itemOnSale = map[int]int64{} // ItemID => OnSale | |
. . 453: itemBuilt = map[int]int{} // ItemID => BuiltCount | |
. . 454: itemBought = map[int]int{} // ItemID => CountBought | |
. 20ms 455: itemBuilding = map[int][]Building{} // ItemID => Buildings | |
. . 456: itemPower0 = map[int]Exponential{} // ItemID => currentTime における Power | |
. . 457: itemBuilt0 = map[int]int{} // ItemID => currentTime における BuiltCount | |
. . 458: | |
. . 459: addingAt = map[int64]Adding{} // Time => currentTime より先の Adding | |
. . 460: buyingAt = map[int64][]Buying{} // Time => currentTime より先の Buying | |
. . 461: ) | |
. . 462: | |
. . 463: for itemID := range mItems { | |
. 20ms 464: itemPower[itemID] = big.NewInt(0) | |
. 30ms 465: itemBuilding[itemID] = []Building{} | |
. . 466: } | |
. . 467: | |
20ms 90ms 468: for _, a := range addings { | |
. . 469: // adding は adding.time に isu を増加させる | |
20ms 20ms 470: if a.Time <= currentTime { | |
20ms 4.80s 471: totalMilliIsu.Add(totalMilliIsu, new(big.Int).Mul(str2big(a.Isu), big1000)) | |
. . 472: } else { | |
. 70ms 473: addingAt[a.Time] = a | |
. . 474: } | |
. . 475: } | |
. . 476: | |
10ms 20ms 477: for _, b := range buyings { | |
. . 478: // buying は 即座に isu を消費し buying.time からアイテムの効果を発揮する | |
. 30ms 479: itemBought[b.ItemID]++ | |
. . 480: m := mItems[b.ItemID] | |
. 300ms 481: totalMilliIsu.Sub(totalMilliIsu, new(big.Int).Mul(m.GetPrice(b.Ordinal), big1000)) | |
. . 482: | |
. . 483: if b.Time <= currentTime { | |
10ms 20ms 484: itemBuilt[b.ItemID]++ | |
. 50ms 485: power := m.GetPower(itemBought[b.ItemID]) | |
10ms 410ms 486: totalMilliIsu.Add(totalMilliIsu, new(big.Int).Mul(power, big.NewInt(currentTime-b.Time))) | |
. 120ms 487: totalPower.Add(totalPower, power) | |
10ms 110ms 488: itemPower[b.ItemID].Add(itemPower[b.ItemID], power) | |
. . 489: } else { | |
. . 490: buyingAt[b.Time] = append(buyingAt[b.Time], b) | |
. . 491: } | |
. . 492: } | |
. . 493: | |
. 20ms 494: totalMilliIsuDiv1000 := new(big.Int).Div(totalMilliIsu, big1000) | |
. 10ms 495: for _, m := range mItems { | |
. 4.11s 496: itemPower0[m.ItemID] = big2exp(itemPower[m.ItemID]) | |
. 30ms 497: itemBuilt0[m.ItemID] = itemBuilt[m.ItemID] | |
. 10ms 498: price := m.GetPrice(itemBought[m.ItemID] + 1) | |
. 10ms 499: itemPrice[m.ItemID] = price | |
. 120ms 500: itemPrice1000[m.ItemID] = new(big.Int).Mul(price, big1000) | |
. . 501: if 0 <= totalMilliIsuDiv1000.Cmp(price) { | |
. . 502: itemOnSale[m.ItemID] = 0 // 0 は 時刻 currentTime で購入可能であることを表す | |
. . 503: } | |
. . 504: } | |
. . 505: | |
. . 506: schedule := []Schedule{ | |
. . 507: Schedule{ | |
. . 508: Time: currentTime, | |
. 3.79s 509: MilliIsu: big2exp(totalMilliIsu), | |
. 3.68s 510: TotalPower: big2exp(totalPower), | |
. . 511: }, | |
. . 512: } | |
. . 513: | |
. . 514: // currentTime から 1000 ミリ秒先までシミュレーションする | |
40ms 40ms 515: for t := currentTime + 1; t <= currentTime+1000; t++ { | |
. 1.49s 516: totalMilliIsu.Add(totalMilliIsu, totalPower) | |
. . 517: updated := false | |
. . 518: | |
. . 519: // 時刻 t で発生する adding を計算する | |
40ms 230ms 520: if a, ok := addingAt[t]; ok { | |
. . 521: updated = true | |
. 240ms 522: totalMilliIsu.Add(totalMilliIsu, new(big.Int).Mul(str2big(a.Isu), big1000)) | |
. . 523: } | |
. . 524: | |
. . 525: // 時刻 t で発生する buying を計算する | |
10ms 100ms 526: if _, ok := buyingAt[t]; ok { | |
. . 527: updated = true | |
. 20ms 528: updatedID := map[int]bool{} | |
. . 529: for _, b := range buyingAt[t] { | |
. . 530: m := mItems[b.ItemID] | |
. 20ms 531: updatedID[b.ItemID] = true | |
. . 532: itemBuilt[b.ItemID]++ | |
. . 533: power := m.GetPower(b.Ordinal) | |
. . 534: itemPower[b.ItemID].Add(itemPower[b.ItemID], power) | |
. . 535: totalPower.Add(totalPower, power) | |
. . 536: } | |
. 20ms 537: for id := range updatedID { | |
. . 538: itemBuilding[id] = append(itemBuilding[id], Building{ | |
. . 539: Time: t, | |
. . 540: CountBuilt: itemBuilt[id], | |
. 1.11s 541: Power: big2exp(itemPower[id]), | |
. . 542: }) | |
. . 543: } | |
. . 544: } | |
. . 545: | |
. . 546: if updated { | |
10ms 50ms 547: schedule = append(schedule, Schedule{ | |
. . 548: Time: t, | |
. 13.10s 549: MilliIsu: big2exp(totalMilliIsu), | |
. 12.65s 550: TotalPower: big2exp(totalPower), | |
. . 551: }) | |
. . 552: } | |
. . 553: | |
. . 554: // 時刻 t で購入可能になったアイテムを記録する | |
50ms 1.91s 555: for itemID := range mItems { | |
120ms 1.83s 556: if _, ok := itemOnSale[itemID]; ok { | |
. . 557: continue | |
. . 558: } | |
60ms 950ms 559: if 0 <= totalMilliIsu.Cmp(itemPrice1000[itemID]) { | |
. . 560: itemOnSale[itemID] = t | |
. . 561: } | |
. . 562: } | |
. . 563: } | |
. . 564: | |
. . 565: gsAdding := []Adding{} | |
. 10ms 566: for _, a := range addingAt { | |
. 20ms 567: gsAdding = append(gsAdding, a) | |
. . 568: } | |
. . 569: | |
. . 570: gsItems := []Item{} | |
. 10ms 571: for itemID, _ := range mItems { | |
. 20ms 572: gsItems = append(gsItems, Item{ | |
. . 573: ItemID: itemID, | |
. . 574: CountBought: itemBought[itemID], | |
. 10ms 575: CountBuilt: itemBuilt0[itemID], | |
. 17.21s 576: NextPrice: big2exp(itemPrice[itemID]), | |
. . 577: Power: itemPower0[itemID], | |
. . 578: Building: itemBuilding[itemID], | |
. . 579: }) | |
. . 580: } | |
. . 581: | |
. . 582: gsOnSale := []OnSale{} | |
10ms 20ms 583: for itemID, t := range itemOnSale { | |
. 10ms 584: gsOnSale = append(gsOnSale, OnSale{ | |
. . 585: ItemID: itemID, | |
. . 586: Time: t, | |
. . 587: }) | |
. . 588: } | |
. . 589: | |
. . 590: return &GameStatus{ | |
. . 591: Adding: gsAdding, | |
. . 592: Schedule: schedule, | |
. . 593: Items: gsItems, | |
. 10ms 594: OnSale: gsOnSale, | |
. . 595: }, nil | |
. . 596:} | |
. . 597: | |
. . 598:func serveGameConn(ws *websocket.Conn, roomName string) { | |
. . 599: log.Println(ws.RemoteAddr(), "serveGameConn", roomName) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment