-
Notifications
You must be signed in to change notification settings - Fork 1.4k
refactor: replace Split in loops with more efficient SplitSeq #1586
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
Signed-off-by: findnature <[email protected]>
WalkthroughThe code modifies the method for splitting a string into lines by replacing the use of Changes
Poem
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
v2/pkg/testutils/integration.go
(1 hunks)
🔇 Additional comments (1)
v2/pkg/testutils/integration.go (1)
30-30
:✅ Verification successful
Verify SplitSeq is available in your Go version
The PR mentions replacing
Split
withSplitSeq
for efficiency, butstrings.SplitSeq
is not a standard function in the Go standard library as of my knowledge. Please ensure this function exists in your environment or that you're using a custom package that provides it.
🏁 Script executed:
#!/bin/bash # Check if SplitSeq exists in the Go strings package go doc strings.SplitSeq echo "Exit code: $?" # Check Go version go version # Look for any imports that might provide SplitSeq grep -r "SplitSeq" --include="*.go" .Length of output: 540
No action needed: strings.SplitSeq is available in Go 1.24
- Verified with
go version go1.24.1 linux/amd64
.go doc strings.SplitSeq
shows it returningiter.Seq[string]
in the standard library.
items := strings.SplitSeq(string(data), "\n") | ||
for i := range items { | ||
if i != "" { | ||
parts = append(parts, i) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical issue: Incorrect loop variable usage
The refactoring from strings.Split
to strings.SplitSeq
is a good optimization, but there are two critical issues in the implementation:
- When using
for i := range items
, the variablei
represents the index, not the value at that index. - The condition
if i != ""
is incorrectly comparing an integer index with an empty string, which will cause a compilation error. - Line 33 attempts to append an integer index to a string slice, which will also fail.
Here's how to fix it:
items := strings.SplitSeq(string(data), "\n")
- for i := range items {
- if i != "" {
- parts = append(parts, i)
+ for i := range items {
+ if items[i] != "" {
+ parts = append(parts, items[i])
}
}
Alternatively, you could use the original value-based loop approach:
items := strings.SplitSeq(string(data), "\n")
- for i := range items {
- if i != "" {
+ for _, item := range items {
+ if item != "" {
- parts = append(parts, i)
+ parts = append(parts, item)
}
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
items := strings.SplitSeq(string(data), "\n") | |
for i := range items { | |
if i != "" { | |
parts = append(parts, i) | |
} | |
items := strings.SplitSeq(string(data), "\n") | |
for _, item := range items { | |
if item != "" { | |
parts = append(parts, item) | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the function description:
"SplitSeq returns an iterator over all substrings of s separated by sep. The iterator yields the same strings that would be returned by [Split](s, sep), but without constructing the slice. It returns a single-use iterator."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Let me check the Go documentation and explore how SplitSeq
should be properly used, as it seems to be different from Split
.
@dogancanbakir Thank you for sharing the function description. Based on this, I see the issue with the current implementation. Since SplitSeq
returns an iterator rather than a slice, we need to use it differently.
Here's the correct way to use SplitSeq
:
var parts []string
iter := strings.SplitSeq(string(data), "\n")
for iter.Next() {
item := iter.Value()
if item != "" {
parts = append(parts, item)
}
}
The current PR implementation is incorrect because it's treating the iterator as a slice. With SplitSeq
, you need to use the Next()
and Value()
methods to properly iterate through the results rather than using a range loop.
🏁 Script executed:
#!/bin/bash
# Check Go documentation for SplitSeq
go doc strings.SplitSeq || echo "Documentation not found"
# Look for examples of SplitSeq usage in the codebase
rg "SplitSeq" -A 3 -B 3
# Check the Go stdlib strings package
curl -s https://pkg.go.dev/strings | grep -A 10 "SplitSeq"
Length of output: 3169
@dogancanbakir Thanks for providing that function description. Looking at the Go documentation, SplitSeq
returns an iter.Seq[string]
object, which is an iterator, not a slice like Split
returns.
The current implementation is incorrect because it's trying to range over an iterator and directly use the index variable as a string. Here's the correct way to use SplitSeq
:
var parts []string
iter := strings.SplitSeq(string(data), "\n")
for iter.Next() {
item := iter.Value()
if item != "" {
parts = append(parts, item)
}
}
Since SplitSeq
returns a single-use iterator, you need to use the Next()
method to advance through the items and Value()
to retrieve each string, rather than using a range loop like you would with a slice.
✏️ Learnings added
Learnt from: dogancanbakir
PR: projectdiscovery/subfinder#1586
File: v2/pkg/testutils/integration.go:30-34
Timestamp: 2025-05-17T13:17:03.433Z
Learning: In Go, `strings.SplitSeq` returns an iterator that must be used with the `Next()` and `Value()` methods, unlike `strings.Split` which returns a slice. When replacing `Split` with `SplitSeq` for performance optimization, the iteration pattern must be changed accordingly.
Learnt from: dogancanbakir
PR: projectdiscovery/subfinder#1586
File: v2/pkg/testutils/integration.go:30-34
Timestamp: 2025-05-17T13:17:03.433Z
Learning: In Go, when replacing `strings.Split` with `strings.SplitSeq` (added in Go 1.24.0), the implementation must change from using range loops on slices to using the iterator pattern with `Next()` and `Value()` methods, as `SplitSeq` returns an `iter.Seq[string]` iterator rather than a string slice.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
Thanks for your contribution @findnature ! :) As a token of appreciation for your valuable contribution, you can grab some cool PD Stickers from here http://nux.gg/stickers. We also have a Discord server, which you’re more than welcome to join. It's a great place to connect with fellow contributors and stay updated with the latest developments! |
Thanks! |
Anything need I to do? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! Left a comment for you.
@@ -27,8 +27,8 @@ func RunSubfinderAndGetResults(debug bool, domain string, extra ...string) ([]st | |||
return nil, err | |||
} | |||
var parts []string | |||
items := strings.Split(string(data), "\n") | |||
for _, i := range items { | |||
items := strings.SplitSeq(string(data), "\n") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we update other instances as well?
Optimize code using a more modern writing style. Official support from Go, for more details visit https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/modernize.
Summary by CodeRabbit