diff --git a/.jules/bolt.md b/.jules/bolt.md index 10d76cf..2bc3043 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -1,3 +1,7 @@ ## 2024-07-01 - Optimizing React rendering with useMemo **Learning:** Found an O(n) array sorting operation and deep recursive countFiles inside the body of a React Function Component (`TreeNode`) which is called many times for deeply nested trees. React components that are pure should memoize their expensive operations instead of doing them synchronously during each render pass. **Action:** Always wrap `children` sorting and recursive tree traversal computations in `React.useMemo` to prevent deep performance degradation during re-renders. + +## 2024-05-19 - Fast LCS Calculation in JavaScript +**Learning:** For dynamic programming algorithms like calculating Longest Common Subsequence (LCS) that allocate large multi-dimensional matrices, using standard arrays via `new Array(n).fill(0)` and `Math.max` calls per cell creates significant overhead. Using `Uint16Array` for flat integer sequences avoids hidden v8 array optimization deopts and reduces memory allocations. Furthermore, in tight nested loops over strings, `String.prototype.charCodeAt(i)` caches far better and avoids single-character string allocations compared to `str[i] === str2[j]`. Finally, avoiding `Math.max` using inline conditionals `a > b ? a : b` significantly reduces overhead. +**Action:** Always favor typed arrays (`Uint16Array`, `Uint8Array`, etc.) over `Array.prototype.fill(0)` when running matrix-based DP in hot loops, and inline min/max evaluations. For string parsing, use `.charCodeAt()` over char extraction where equality is being checked. diff --git a/src/lib/parser.js b/src/lib/parser.js index 95692a7..de752ce 100644 --- a/src/lib/parser.js +++ b/src/lib/parser.js @@ -761,26 +761,24 @@ const Parser={ // Longest common subsequence length (optimized for similarity) lcsLength:function(s1,s2){ // Use simplified approach for performance - if(s1.length>500||s2.length>500){ - // For long strings, use sampling - s1=s1.substring(0,500); - s2=s2.substring(0,500); - } + if(s1.length>500) s1=s1.substring(0,500); + if(s2.length>500) s2=s2.substring(0,500); var m=s1.length,n=s2.length; - var prev=new Array(n+1).fill(0); - var curr=new Array(n+1).fill(0); + var prev=new Uint16Array(n+1); + var curr=new Uint16Array(n+1); for(var i=1;i<=m;i++){ + var c1=s1.charCodeAt(i-1); for(var j=1;j<=n;j++){ - if(s1[i-1]===s2[j-1]){ + if(c1===s2.charCodeAt(j-1)){ curr[j]=prev[j-1]+1; }else{ - curr[j]=Math.max(prev[j],curr[j-1]); + var p=prev[j],c=curr[j-1]; + curr[j]=p>c?p:c; } } var tmp=prev;prev=curr;curr=tmp; - curr.fill(0); } return prev[n]; },