-
Notifications
You must be signed in to change notification settings - Fork 0
⚡ Optimize activity event loop with Sakamoto's algorithm #295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -707,20 +707,26 @@ export const fetchActivity = cache(async function fetchActivity( | |||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| const eventCountMap = new Map<string, number>(); | ||||||||||||||||||||||||||||||||||||||||||||||||
| const dayCache = new Map<string, number>(); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| for (const event of allEvents) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| const createdAt = event.created_at; | ||||||||||||||||||||||||||||||||||||||||||||||||
| const datePart = createdAt.slice(0, 10); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| let day = dayCache.get(datePart); | ||||||||||||||||||||||||||||||||||||||||||||||||
| if (day === undefined) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| day = new Date(datePart).getUTCDay(); // 0=Sun, 6=Sat | ||||||||||||||||||||||||||||||||||||||||||||||||
| dayCache.set(datePart, day); | ||||||||||||||||||||||||||||||||||||||||||||||||
| // Fast day extraction from YYYY-MM-DD | ||||||||||||||||||||||||||||||||||||||||||||||||
| const charCodeZero = '0'.charCodeAt(0); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
709
to
+715
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Prompt To Fix With AIThis is a comment left during a code review.
Path: src/lib/github.ts
Line: 709-715
Comment:
**ループ内で `charCodeZero` を毎回計算している**
`'0'.charCodeAt(0)` は常に `48` の不変値ですが、現在はループの各イテレーションで評価されています。ループの外に定数として巻き上げることで、無駄な関数呼び出しを排除できます。
```suggestion
const eventCountMap = new Map<string, number>();
const charCodeZero = '0'.charCodeAt(0);
const sakamotoT = [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4];
for (const event of allEvents) {
const createdAt = event.created_at;
// Fast day extraction from YYYY-MM-DD
```
How can I resolve this? If you propose a fix, please make it concise. |
||||||||||||||||||||||||||||||||||||||||||||||||
| const y = (createdAt.charCodeAt(0) - charCodeZero) * 1000 + (createdAt.charCodeAt(1) - charCodeZero) * 100 + (createdAt.charCodeAt(2) - charCodeZero) * 10 + (createdAt.charCodeAt(3) - charCodeZero); | ||||||||||||||||||||||||||||||||||||||||||||||||
| const m = (createdAt.charCodeAt(5) - charCodeZero) * 10 + (createdAt.charCodeAt(6) - charCodeZero); | ||||||||||||||||||||||||||||||||||||||||||||||||
| const d = (createdAt.charCodeAt(8) - charCodeZero) * 10 + (createdAt.charCodeAt(9) - charCodeZero); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| // Sakamoto's algorithm for day of week | ||||||||||||||||||||||||||||||||||||||||||||||||
| const t = [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4]; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Prompt To Fix With AIThis is a comment left during a code review.
Path: src/lib/github.ts
Line: 721
Comment:
**ループ内での配列アロケーション — 最適化の逆効果**
`const t = [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4]` がループの内側で毎イテレーション新規に 12 要素配列を生成しています。PR 説明で「中間メモリのガーベジをほぼ排除」と謳っているにもかかわらず、100,000 回のイベント処理では同数の配列オブジェクトが生まれ続けます。`dayCache` の `Map` オーバーヘッドを除去した恩恵をほぼ相殺してしまいます。`t` はループの外側(あるいは `fetchActivity` 関数スコープの外)で定数として定義すべきです。
How can I resolve this? If you propose a fix, please make it concise. |
||||||||||||||||||||||||||||||||||||||||||||||||
| let sy = y; | ||||||||||||||||||||||||||||||||||||||||||||||||
| if (m < 3) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| sy -= 1; | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| const day = (sy + Math.floor(sy/4) - Math.floor(sy/100) + Math.floor(sy/400) + t[m-1] + d) % 7; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+715
to
+726
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With the constants moved outside the loop, the logic here can be simplified. Additionally, per repository rules, manually parsed numeric values like the month
Suggested change
References
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| // Fast hour extraction from YYYY-MM-DDTHH:MM:SSZ | ||||||||||||||||||||||||||||||||||||||||||||||||
| const charCodeZero = '0'.charCodeAt(0); | ||||||||||||||||||||||||||||||||||||||||||||||||
| // charCodeZero is already defined above | ||||||||||||||||||||||||||||||||||||||||||||||||
| const hour = (createdAt.charCodeAt(11) - charCodeZero) * 10 + (createdAt.charCodeAt(12) - charCodeZero); | ||||||||||||||||||||||||||||||||||||||||||||||||
| heatmap[day][hour]++; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To maximize the performance benefits of this optimization, move the
charCodeZeroconstant and the Sakamoto lookup tabletoutside of the loop. Defining them inside the loop causes unnecessary re-allocations and assignments in every iteration of the activity processing loop.