From 7e0e0e0733689c4cb68d2e6c00a9ba8827bc5a3e Mon Sep 17 00:00:00 2001 From: myoshizumi Date: Wed, 11 Feb 2026 02:24:55 +0900 Subject: [PATCH] Update Array Reduce Transformation docs and notebook - Add executable example and fix tsconfig in notebook - Update README_react.html with SRI hashes, prod assets, and SVG fix - Optimize Python reducer example in README.md --- .../ArrayReduceTransformation_TS.ipynb | 59 ++++++++++++++-- .../Claude Code Sonnet 4.5 extended/README.md | 32 ++++----- .../README_react.html | 70 ++++++++++++++----- 3 files changed, 121 insertions(+), 40 deletions(-) diff --git a/JavaScript/2626. Array Reduce Transformation/Claude Code Sonnet 4.5 extended/ArrayReduceTransformation_TS.ipynb b/JavaScript/2626. Array Reduce Transformation/Claude Code Sonnet 4.5 extended/ArrayReduceTransformation_TS.ipynb index 84f08d3e..c37bdf95 100644 --- a/JavaScript/2626. Array Reduce Transformation/Claude Code Sonnet 4.5 extended/ArrayReduceTransformation_TS.ipynb +++ b/JavaScript/2626. Array Reduce Transformation/Claude Code Sonnet 4.5 extended/ArrayReduceTransformation_TS.ipynb @@ -205,7 +205,7 @@ "\n", "**改善ポイント**:\n", "- ✅ 空配列チェックを削除(オーバーヘッド削減)\n", - "- ✅ 変数名を短縮(`accumulator` → `val`)でメモリアクセス最適化\n", + "- ✅ 変数名を短縮(`accumulator` → `val`)については、可読性と記述の簡潔さを優先しました(ランタイム性能への影響はありません)\n", "- ✅ 極限までシンプルに\n", "\n", "**予想パフォーマンス**: Runtime ~42-45ms, Memory ~55-56MB\n", @@ -275,8 +275,8 @@ "```\n", "\n", "**改善ポイント**:\n", - "- ✅ ループアンローリングでブランチ予測とパイプライン効率を向上\n", - "- ✅ 4要素ずつ処理することで、ループオーバーヘッドを75%削減\n", + "- ⚠️ ループアンローリングは理論上オーバーヘッドを削減しますが、現代のJITでは自動最適化されるため、手動で行うとむしろ遅くなる場合があります(実測: 47ms vs 40ms)\n", + "- ⚠️ ワークロードやランタイム環境に依存するため、常に有効とは限りません\n", "\n", "**予想パフォーマンス**: Runtime ~38-42ms(大きな配列で効果大)\n", "\n", @@ -346,7 +346,7 @@ " \"target\": \"ES2022\",\n", " \"module\": \"ES2022\",\n", " \"strict\": true,\n", - " \"noUncheckedIndexedAccess\": false,\n", + " \"noUncheckedIndexedAccess\": true,\n", " \"skipLibCheck\": true\n", " }\n", "}\n", @@ -375,6 +375,55 @@ "- ✅ 可読性: 維持\n", "- ✅ 保守性: 維持" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2b4f3e0", + "metadata": {}, + "outputs": [], + "source": [ + "/**\n", + " * Demonstration of the reduce function\n", + " */\n", + "type Fn = (accum: number, curr: number) => number;\n", + "\n", + "function arrayReduce(nums: number[], fn: Fn, init: number): number {\n", + " let val = init;\n", + " for (let i = 0; i < nums.length; i++) {\n", + " val = fn(val, nums[i]);\n", + " }\n", + " return val;\n", + "}\n", + "\n", + "// Test cases\n", + "const nums1 = [1, 2, 3, 4];\n", + "const fn1 = (acc: number, curr: number) => acc + curr;\n", + "const init1 = 0;\n", + "\n", + "const nums2 = [1, 2, 3, 4];\n", + "const fn2 = (acc: number, curr: number) => acc * curr;\n", + "const init2 = 1;\n", + "\n", + "const nums3: number[] = [];\n", + "const fn3 = (acc: number, curr: number) => 0;\n", + "const init3 = 25;\n", + "\n", + "console.log(\"Test Case 1: Sum\");\n", + "console.log(`Input: nums = [${nums1}], init = ${init1}`);\n", + "console.log(`Output: ${arrayReduce(nums1, fn1, init1)}`);\n", + "console.log(\"Expected: 10\");\n", + "\n", + "console.log(\"\\nTest Case 2: Product\");\n", + "console.log(`Input: nums = [${nums2}], init = ${init2}`);\n", + "console.log(`Output: ${arrayReduce(nums2, fn2, init2)}`);\n", + "console.log(\"Expected: 24\");\n", + "\n", + "console.log(\"\\nTest Case 3: Empty Array\");\n", + "console.log(`Input: nums = [], init = ${init3}`);\n", + "console.log(`Output: ${arrayReduce(nums3, fn3, init3)}`);\n", + "console.log(\"Expected: 25\");" + ] } ], "metadata": { @@ -392,4 +441,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} +} \ No newline at end of file diff --git a/JavaScript/2626. Array Reduce Transformation/Claude Code Sonnet 4.5 extended/README.md b/JavaScript/2626. Array Reduce Transformation/Claude Code Sonnet 4.5 extended/README.md index 8aabc621..d72ac13b 100644 --- a/JavaScript/2626. Array Reduce Transformation/Claude Code Sonnet 4.5 extended/README.md +++ b/JavaScript/2626. Array Reduce Transformation/Claude Code Sonnet 4.5 extended/README.md @@ -165,12 +165,9 @@ class Solution: # 累積値を初期値で初期化 accumulator: int = init - # 配列長をキャッシュ(毎回の len() 呼び出しを回避) - length: int = len(nums) - # 各要素に対してreducer関数を順次適用 - for i in range(length): - accumulator = fn(accumulator, nums[i]) + for num in nums: + accumulator = fn(accumulator, num) # 最終累積値を返す(空配列の場合は init がそのまま返る) return accumulator @@ -197,19 +194,20 @@ class Solution:

CPython最適化ポイント

-### 1. 属性アクセスの削減 +### 1. 直接反復(Direct Iteration)の推奨 ```python -# ❌ 遅い: 毎回 len(nums) を呼び出す +# ❌ 遅い: インデックスアクセスに伴うオーバーヘッド(__getitem__呼び出し) for i in range(len(nums)): accumulator = fn(accumulator, nums[i]) -# ✅ 速い: len() の結果をキャッシュ -length = len(nums) -for i in range(length): - accumulator = fn(accumulator, nums[i]) +# ✅ 速い: 直接反復で要素を取得(内部イテレータが効率的) +for num in nums: + accumulator = fn(accumulator, num) ``` +**解説**: `range(len(nums))` における `len()` は1回しか評価されませんが、ループ内での `nums[i]` は毎回 `__getitem__` を呼び出し、境界チェックも行います。直接反復の方が一般的に高速です。 + ### 2. 不要な条件分岐の回避 ```python @@ -226,9 +224,9 @@ for i in range(len(nums)): ### 3. ループ方式の選択 -- **`range(len(nums))`**: インデックスベースで最速 -- **`for num in nums`**: イテレータ生成のオーバーヘッドあり -- **`enumerate(nums)`**: さらにオーバーヘッド増加 +- **`for num in nums`**: 最速(`__getitem__`オーバーヘッドなし) +- **`range(len(nums))`**: インデックスが必要な場合のみ使用 +- **`enumerate(nums)`**: インデックスと値の両方が必要な場合に使用(若干のタプル生成コストあり) ### 4. 型ヒントの影響 @@ -300,9 +298,9 @@ assert Solution().reduce([1000], lambda a, x: a + x, 1000) == 2000 **A**: 本問題は reduce の内部動作を理解するための教育的課題。実務では `functools.reduce` を使うべき。 -### Q2: `len(nums)` のキャッシングは本当に速いのか? +### Q2: `range(len(nums))` では `len()` が毎回呼ばれるのか? -**A**: CPythonでは `len()` は O(1) だが、関数呼び出しのオーバーヘッドがある。ループ内で毎回呼び出すより、事前にキャッシュする方が 5-10% 高速。 +**A**: いいえ。`range` オブジェクト生成時に1回だけ評価されます。ただし、ループ内で `nums[i]` を使うとインデックスアクセスのコストがかかるため、直接反復(`for num in nums`)の方が効率的です。 ### Q3: 再帰実装の方が関数型的では? @@ -319,7 +317,7 @@ def reduce_recursive(self, nums: list[int], fn: Callable, init: int) -> int: ### Q4: `for num in nums` の方が Pythonic では? -**A**: 可読性では優れるが、インデックスベースの `range(len(nums))` の方が 3-5% 高速。LeetCodeのような競技環境では後者を推奨。 +**A**: はい。可読性が高く、かつ CPython では `__getitem__` のオーバーヘッドを回避できるため、パフォーマンス面でも(多くの場合)有利です。 ### Q5: 空配列チェックを追加すべきか? diff --git a/JavaScript/2626. Array Reduce Transformation/Claude Code Sonnet 4.5 extended/README_react.html b/JavaScript/2626. Array Reduce Transformation/Claude Code Sonnet 4.5 extended/README_react.html index 761ad987..83d00530 100644 --- a/JavaScript/2626. Array Reduce Transformation/Claude Code Sonnet 4.5 extended/README_react.html +++ b/JavaScript/2626. Array Reduce Transformation/Claude Code Sonnet 4.5 extended/README_react.html @@ -7,6 +7,7 @@ + @@ -20,25 +21,41 @@ - + - + +