* style(simd): rename sse to avx
* fix(exp,simd): apply the right avx512 constraints to a few methods
* fix(exp,simd): apply the right avx512 constraints to a few methods
- Replace Nth() with NthOrEmpty() to avoid unnecessary error allocation on miss
- Change make(0, size) + append to make(size) + direct assignment
- Use uint for loop indices
- Remove temporary variables in ZipBy functions
This reduces overhead from append operations and structure creation,
similar to the Zip5Copy2 optimization pattern.
Reduces code size: +174/-242 lines
Extract core logic into sliceNth/seqNth func returning (T, bool) instead of (T, error).
NthOr and NthOrEmpty now use these directly,
avoiding fmt.Errorf allocation when nth is out of bounds.
- RangeWithSteps now preallocates result slice using math.Ceil for better performance
- Fix edge cases for floating point values with small steps
- Add test cases for float and custom type validation
- Rename TestRangeClose → TestRangeWithSteps for consistency
- Simplify ChunkEntries chunk count calculation using ((count-1)/size)+1 formula
Replace shared next struct and reused stop variable with separate
nextA, stopA, nextB, stopB, etc.
Improves code clarity and eliminates potential confusion from variable reuse.
Fixed DropByIndex function for the case when a negative index exceeds
the slice size. This caused subsequent indices to have incorrect
offsets, leading to incorrect results.
Example of the bug:
DropByIndex([]int{0, 1, 2, 3, 4}, -100, 4)
returned []int{0, 1, 2, 4} instead of []int{0, 1, 2, 3}
Improvements:
- Removed map-based uniqueness check, now uses sorted iteration with O(1) memory
- Added copy of indexes to prevent mutation of input
- Fixed negative index handling logic
- Improved range check using uint for proper bounds validation
Performance:
- Time: -75.61% (geomean)
- Memory: -62.65% (geomean)
- Allocations: -43.67% (geomean)
Additional:
- Optimized Filter and FilterI in mutable/slice.go
* fix: make Ellipsis operate on runes instead of bytes to prevent Unicode truncation
The Ellipsis function previously used byte-based length counting (len(str))
and byte-based slicing (str[:length-3]), which could split multi-byte
Unicode characters in the middle, producing garbled output.
This changes the function to use []rune conversion so the length parameter
counts Unicode code points instead of bytes. Emoji, CJK ideographs, and
other multi-byte characters are now never split in the middle.
Fixes#520
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: avoid rune slice allocation in Ellipsis
Use range-based iteration to count runes without allocating a []rune
slice, per reviewer suggestion. The early-return for length < 3 is
kept explicit for clarity.
* Simplify Ellipsis: remove early return for length < 3, reuse ellipsis const
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- Replace Range+MinBy with MinIndexBy in DispatchingStrategyLeast for better performance
- Replace Range+MaxBy with MaxIndexBy in DispatchingStrategyMost for better performance
- Use range loop in DispatchingStrategyWeightedRandom for better readability
- Simplify Buffer function by using local variable in for loop and returning size directly
These changes reduce allocations and improve performance by using more efficient
index-finding functions instead of creating intermediate slices with Range().
Change Trim to use DropLastWhile(DropWhile(...)) instead of DropWhile(DropLastWhile(...))
This is more efficient because DropWhile doesn't use a buffer, so it removes
leading elements first, then DropLastWhile works with a smaller collection.
Regression introduced in 1c66270 (perf: preallocate result slice in SamplesBy) where
`make(Slice, count)` with negative count causes panic. Previously used
`Slice{}` with `append`, which handled negative counts gracefully.
- Simplify NthOrEmpty by removing redundant error handling
- Simplify Sample by removing intermediate variable
- Refactor SamplesBy to use index tracking instead of collection copying
- More efficient: avoids copying the entire collection
- Uses Range to generate indexes and swaps/removes from index slice
- Uses `n := len(indexes)` to eliminate redundant bounds checks
- Add early return for count <= 0 in SamplesBy (fixes panic with make)
- Add edge case tests for SamplesBy:
- Test with deterministic random generators (always last index, always 0)
- Test count = 0 and count = -1 (verifies non-panic behavior)
- Add panic test for out-of-range index generation
- Fix docstring: clarify Slice returns a slice view, not a copy
- Reorder boundary checks to use else-if
- Add test case for negative start and end indices
- CutPrefix now uses HasPrefix instead of manual comparison loop
- CutSuffix now uses HasSuffix instead of manual comparison loop
- TrimPrefix simplified with HasPrefix condition in for loop
- TrimSuffix simplified with HasSuffix condition in for loop
This reduces code duplication and improves readability.
- Consume iterators with for range instead of discarding with _ =
Previously iterators were created but never consumed, giving misleading
performance results (~0.3 ns/op) that only measured iterator creation
- Add BenchmarkItDropLastWhile for testing DropLastWhile performance
- Add BenchmarkItTrim for testing Trim performance
- Add BenchmarkItTrimSuffix for testing TrimSuffix performance
- Replace for better readability `for i := 0; i < n; i++` with `for i := range n`
This fix ensures benchmarks measure actual iterator execution time
rather than just iterator creation time, which is critical for lazy
iterators that don't execute until consumed.
Track exact duplicate count during detection phase instead of
incorrect estimating capacity as len(collection)-len(isDupl).
Also simplify map update logic and rename ok -> seen for clarity.