Skip to content

Commit 78bbe34

Browse files
committed
docs(JavaScript): replace absolute performance claims between in and ??= with semantic guidance and IC benchmark nuances
1 parent 4494399 commit 78bbe34

4 files changed

Lines changed: 31 additions & 24 deletions

File tree

JavaScript/2631. Group By/Claude Code Sonnet 4.6 extended/Group_By_TS.ipynb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@
153153
" const item = this[i]; // ③ 一時変数でthis参照を1回に抑制\n",
154154
" const key = fn(item);\n",
155155
"\n",
156-
" // ④ in演算子で存在確認 → ??=より軽量(型変換コストなし)\n",
156+
" // ④ Object.create(null) に対するキー存在確認のセマンティクス\n",
157157
" if (key in result) {\n",
158158
" result[key].push(item);\n",
159159
" } else {\n",
@@ -188,12 +188,12 @@
188188
"for (let i = 0; i < len; i++)\n",
189189
"```\n",
190190
"\n",
191-
"**③ `??=` `in` 演算子**\n",
191+
"**③ `??=` `in` 演算子**\n",
192192
"```typescript\n",
193-
"// Before: ??= は内部でnullish判定 + 代入の2ステップ\n",
193+
"// パターンA: ??= を用いた記述(V8環境でIC最適化が効きやすい)\n",
194194
"(acc[key] ??= []).push(item);\n",
195195
"\n",
196-
"// After: プロパティ存在確認のみ(型変換コストゼロ\n",
196+
"// パターンB: in 演算子による存在確認(本実装での採用\n",
197197
"if (key in result) {\n",
198198
" result[key].push(item);\n",
199199
"} else {\n",

JavaScript/2631. Group By/Claude Code Sonnet 4.6 extended/README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
- **データ構造**: `Object.create(null)` による純粋なハッシュマップ(プロトタイプ汚染なし)
4242
- **時間計算量**: O(n) — 全要素を1回走査
4343
- **空間計算量**: O(n) — 結果オブジェクトに全要素を格納
44-
- **最適化ポイント**: `reduce` よりも `for` ループがスタックフレームを節約、`length` キャッシュでプロパティ参照コスト削減、`??=` より `in` 演算子が軽量
44+
- **最適化ポイント**: `reduce` よりも `for` ループがスタックフレームを節約、`length` キャッシュでプロパティ参照コスト削減、キーの存在確認におけるセマンティクスの違い(`Object.create(null)` `in` 演算子)
4545
- **プロトタイプ拡張**: `interface Array<T>` の Declaration Merging で型安全性を維持
4646

4747
---
@@ -201,20 +201,23 @@ const len = this.length;
201201
for (let i = 0; i < len; i++)
202202
```
203203

204-
### 3. `??=` `in` 演算子
204+
### 3. `??=` `in` 演算子
205205

206206
```typescript
207-
// Before: nullish判定 + 条件付き代入 の2ステップ
207+
// パターンA: ??= を用いた簡潔な記述
208208
(acc[key] ??= []).push(item);
209209

210-
// After: プロパティ存在確認のみ(内部的により単純な操作
210+
// パターンB: in 演算子による存在確認(本実装での採用
211211
if (key in result) {
212212
result[key].push(item);
213213
} else {
214214
result[key] = [item];
215215
}
216216
```
217217

218+
- `Object.create(null)` で作成されたプロトタイプを持たないオブジェクトに対しては、キーの存在確認としてセマンティクス上 `in` 演算子が適しています。
219+
- ただし V8 などの JS エンジンでは、インラインキャッシュ(IC)の最適化が働きやすいため、実環境上のマイクロベンチマークでは `??=` を用いた方が高速に動作するケースも多く見られます。パフォーマンスの優劣については、絶対指標ではなく実行環境や最適化状況に依存します。
220+
218221
### 4. `Object.create(null)` によるプロトタイプ汚染防止
219222

220223
```typescript

JavaScript/2631. Group By/Claude Code Sonnet 4.6 extended/README_react.html

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,8 @@ <h3 class="outfit font-bold text-teal-800 text-lg mb-3">最適化のポイント
273273
<li class="flex items-start gap-2">
274274
<span class="text-emerald-500 font-bold text-base leading-5"></span>
275275
<span
276-
><strong class="text-slate-700">in 演算子</strong>??=
277-
より軽量なキー存在確認</span
276+
><strong class="text-slate-700">in 演算子 vs ??=</strong
277+
>:キーの存在確認におけるセマンティクスの違い(Object.create(null)との併用)</span
278278
>
279279
</li>
280280
<li class="flex items-start gap-2">
@@ -337,7 +337,7 @@ <h3 class="outfit font-bold text-teal-800 text-lg mb-3">最適化のポイント
337337
const item = this[i]; // ③ this 参照を1回に抑制
338338
const key = fn(item); // コールバックでキーを生成
339339

340-
// ④ in 演算子: ??= より軽量(型変換コストなし)
340+
// ④ in 演算子: プロトタイプなしオブジェクトのキー存在確認
341341
if (key in result) {
342342
result[key].push(item); // キー存在: 既存配列へ追加
343343
} else {
@@ -1336,7 +1336,7 @@ <h3 class="outfit font-bold text-teal-800 text-lg mb-3">最適化のポイント
13361336
className="slide-in mt-4 rounded-xl overflow-hidden border border-slate-200"
13371337
>
13381338
<div className="bg-slate-700 text-white text-xs px-4 py-2 font-bold">
1339-
キー存在確認フロー(in 演算子 vs ??=)
1339+
キー存在確認フロー(in 演算子と ??= の違い
13401340
</div>
13411341
<div className="bg-slate-900 text-slate-200 p-4 text-xs mono leading-6">
13421342
<div className="text-slate-400">{'// ✅ in 演算子(推奨)'}</div>
@@ -1361,10 +1361,12 @@ <h3 class="outfit font-bold text-teal-800 text-lg mb-3">最適化のポイント
13611361
</div>
13621362
<div>{'}'}</div>
13631363
<div className="mt-3 text-slate-400">
1364-
{'// ??= (比較: nullish判定+代入の2ステップ)'}
1364+
{'// ??= (Nullish coalescing assignment)'}
13651365
</div>
13661366
<div className="text-red-400">
1367-
{'(acc[key] ??= []).push(item); // やや重い'}
1367+
{
1368+
'(acc[key] ??= []).push(item); // V8のIC最適化が効きやすいケースもある'
1369+
}
13681370
</div>
13691371
</div>
13701372
</div>
@@ -1543,7 +1545,7 @@ <h3 className="outfit mt-0 text-teal-800 text-lg font-bold">
15431545
const beforeCode = `Array.prototype.groupBy = function(fn) {
15441546
// ❌ reduce: n回スタックフレーム生成
15451547
return this.reduce((acc, item) => {
1546-
// ??= : nullish判定+代入の2ステップ
1548+
// ??= : V8最適化が効きやすい簡潔な記法
15471549
(acc[fn(item)] ??= []).push(item);
15481550
return acc;
15491551
}, {}); // ❌ {} : プロトタイプ汚染リスク
@@ -1693,7 +1695,7 @@ <h3 className="outfit mt-0 text-teal-800 text-lg font-bold">
16931695
'毎ループ this.length',
16941696
'const len にキャッシュ',
16951697
],
1696-
['キー確認', '??=(2ステップ)', 'in演算子(1ステップ)'],
1698+
['キー確認', '??= 演算子', 'in 演算子'],
16971699
['Memory Beats', '~40%', '~70%+'],
16981700
].map(([point, before, after]) => (
16991701
<tr key={point} className="hover:bg-slate-50">

public/JavaScript/2631. Group By/Claude Code Sonnet 4.6 extended/README_react.html

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,8 @@ <h3 class="outfit font-bold text-teal-800 text-lg mb-3">最適化のポイント
273273
<li class="flex items-start gap-2">
274274
<span class="text-emerald-500 font-bold text-base leading-5"></span>
275275
<span
276-
><strong class="text-slate-700">in 演算子</strong>??=
277-
より軽量なキー存在確認</span
276+
><strong class="text-slate-700">in 演算子 vs ??=</strong
277+
>:キーの存在確認におけるセマンティクスの違い(Object.create(null)との併用)</span
278278
>
279279
</li>
280280
<li class="flex items-start gap-2">
@@ -337,7 +337,7 @@ <h3 class="outfit font-bold text-teal-800 text-lg mb-3">最適化のポイント
337337
const item = this[i]; // ③ this 参照を1回に抑制
338338
const key = fn(item); // コールバックでキーを生成
339339

340-
// ④ in 演算子: ??= より軽量(型変換コストなし)
340+
// ④ in 演算子: プロトタイプなしオブジェクトのキー存在確認
341341
if (key in result) {
342342
result[key].push(item); // キー存在: 既存配列へ追加
343343
} else {
@@ -1336,7 +1336,7 @@ <h3 class="outfit font-bold text-teal-800 text-lg mb-3">最適化のポイント
13361336
className="slide-in mt-4 rounded-xl overflow-hidden border border-slate-200"
13371337
>
13381338
<div className="bg-slate-700 text-white text-xs px-4 py-2 font-bold">
1339-
キー存在確認フロー(in 演算子 vs ??=)
1339+
キー存在確認フロー(in 演算子と ??= の違い
13401340
</div>
13411341
<div className="bg-slate-900 text-slate-200 p-4 text-xs mono leading-6">
13421342
<div className="text-slate-400">{'// ✅ in 演算子(推奨)'}</div>
@@ -1361,10 +1361,12 @@ <h3 class="outfit font-bold text-teal-800 text-lg mb-3">最適化のポイント
13611361
</div>
13621362
<div>{'}'}</div>
13631363
<div className="mt-3 text-slate-400">
1364-
{'// ??= (比較: nullish判定+代入の2ステップ)'}
1364+
{'// ??= (Nullish coalescing assignment)'}
13651365
</div>
13661366
<div className="text-red-400">
1367-
{'(acc[key] ??= []).push(item); // やや重い'}
1367+
{
1368+
'(acc[key] ??= []).push(item); // V8のIC最適化が効きやすいケースもある'
1369+
}
13681370
</div>
13691371
</div>
13701372
</div>
@@ -1543,7 +1545,7 @@ <h3 className="outfit mt-0 text-teal-800 text-lg font-bold">
15431545
const beforeCode = `Array.prototype.groupBy = function(fn) {
15441546
// ❌ reduce: n回スタックフレーム生成
15451547
return this.reduce((acc, item) => {
1546-
// ??= : nullish判定+代入の2ステップ
1548+
// ??= : V8最適化が効きやすい簡潔な記法
15471549
(acc[fn(item)] ??= []).push(item);
15481550
return acc;
15491551
}, {}); // ❌ {} : プロトタイプ汚染リスク
@@ -1693,7 +1695,7 @@ <h3 className="outfit mt-0 text-teal-800 text-lg font-bold">
16931695
'毎ループ this.length',
16941696
'const len にキャッシュ',
16951697
],
1696-
['キー確認', '??=(2ステップ)', 'in演算子(1ステップ)'],
1698+
['キー確認', '??= 演算子', 'in 演算子'],
16971699
['Memory Beats', '~40%', '~70%+'],
16981700
].map(([point, before, after]) => (
16991701
<tr key={point} className="hover:bg-slate-50">

0 commit comments

Comments
 (0)