Precise DOM morphing
morphing typescript dom
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Optimize LIS reconstruction in child reordering

Use pre-sized LIS buffers and Int32Array predecessor tracking to reduce allocations and avoid unshift-heavy reconstruction in the reordering hot path while preserving behavior.

+18 -29
+18 -29
src/morphlex.ts
··· 946 946 const n = sequence.length 947 947 if (n === 0) return [] 948 948 949 - // smallestEnding[i] = smallest ending value of any increasing subsequence of length i+1 950 - const smallestEnding: Array<number> = [] 951 - // indices[i] = index in sequence where smallestEnding[i] occurs 952 - const indices: Array<number> = [] 953 - // prev[i] = previous index in the LIS ending at sequence[i] 954 - const prev: Array<number> = new Array(n) 949 + const smallestEnding = new Array<number>(n) 950 + const indices = new Array<number>(n) 951 + const prev = new Int32Array(n) 952 + prev.fill(-1) 955 953 956 - // Build the LIS by processing each value 954 + let lisLength = 0 955 + 957 956 for (let i = 0; i < n; i++) { 958 957 const val = sequence[i] 959 - if (val === undefined) continue // Skip new nodes (not in original sequence) 958 + if (val === undefined) continue 960 959 961 - // Binary search: find where this value fits in smallestEnding 962 960 let left = 0 963 - let right = smallestEnding.length 961 + let right = lisLength 964 962 965 963 while (left < right) { 966 964 const mid = Math.floor((left + right) / 2) ··· 968 966 else right = mid 969 967 } 970 968 971 - // Link this element to the previous one in the subsequence 972 969 prev[i] = left > 0 ? indices[left - 1]! : -1 973 970 974 - // Either extend the sequence or update an existing position 975 - if (left === smallestEnding.length) { 976 - // Extend: this value is larger than all previous endings 977 - smallestEnding.push(val) 978 - indices.push(i) 979 - } else { 980 - // Update: found a better (smaller) ending for this length 981 - smallestEnding[left] = val 982 - indices[left] = i 983 - } 971 + smallestEnding[left] = val 972 + indices[left] = i 973 + if (left === lisLength) lisLength++ 984 974 } 985 975 986 - // Reconstruct the actual indices that form the LIS 987 - const result: Array<number> = [] 988 - if (indices.length === 0) return result 976 + if (lisLength === 0) return [] 977 + 978 + const result = new Array<number>(lisLength) 979 + let curr = indices[lisLength - 1]! 989 980 990 - // Walk backwards through prev links to build the LIS 991 - let curr: number | undefined = indices[indices.length - 1] 992 - while (curr !== undefined && curr !== -1) { 993 - result.unshift(curr) 994 - curr = prev[curr] 981 + for (let i = lisLength - 1; i >= 0; i--) { 982 + result[i] = curr 983 + curr = prev[curr]! 995 984 } 996 985 997 986 return result