> On Mar 18, 2025, at 8:40 PM, Ian Lance Taylor <[email protected]> wrote:
>
> On Tue, Mar 18, 2025 at 4:51 PM Mike Schinkel <[email protected]> wrote:
>>
>> While working on a parser, I've repeatedly encountered patterns like:
>>
>> if c == ' ' || c == '\t' { /* handle whitespace */ }
>> if token == EOL || token == EOF { /* handle end markers */ }
>> if lexer.Type == TextLine || lexer.Type == WhitespaceLine { /* handle
>> lines */ }
>>
>> Go already allows multiple values in case statements:
>>
>> switch c {
>> case ' ', '\t':
>> /* handle whitespace */
>> }
>>
>> I'm wondering if there could be a more elegant way to express this pattern
>> in Go, perhaps something conceptually similar to:
>>
>> if c [some_syntax] ' ', '\t' { /* handle whitespace */ }
>>
>> Do you think that the Go team would be likely to consider such a proposal,
>> or would taking the time to prepare and submit a proposal likely just be for
>> naught?
>>
>> If this seems worthy of a proposal, what syntax do you think might be the
>> best fit for the Go language?
>
> We can already write
>
> func Is[T comparable](s T, vals ...T) bool {
> for _, v := range vals {
> if s == v {
> return true
> }
> }
> return false
> }
>
> and then we can write
>
> if Is(c, ' ', '\t') {
> ...
> }
>
> So I don't see a big need for additional syntax here.
Hi Ian,
Thank you for your quick reply. I appreciate your suggestion of using a generic
function approach.
After your response, I wondered about the performance difference so I wrote
some performance benchmarking to see if there is a tangible difference. to
better understand the implications of different approaches to membership
testing.
I wrote a benchmark checking four dimensions including:
• Different techniques (OR expressions, switch statements, generic
functions)
• Small vs. large sets of values (3 and 26 characters)
• Different positions in the value set (first, middle, last, no match)
• Different value sources (literals, constants, variables, method calls)
The results indicated a material difference for when performance is a top
concern. While the generic function approach does work, it comes with a
performance cost compared to switch statements:
• Median case: Generic function is 78% slower than switch case. I
figure this is the common case.
• Average case: Generic function is 131% slower than switch case
• Worst cases: Up to 181% or more slower in scenarios with a large
number of values to compare to
These performance differences are magnified in parser implementations.
The complete benchmark results are here:
https://docs.google.com/spreadsheets/d/15cddzW8xG5JHYzPzu_u6XsXdoQ8Uh_6nVKslwODNSu0/edit?usp=sharing
Anyone reading this with any concerns please check the logic of my benchmarks
and analysis (source found here:
https://gist.github.com/mikeschinkel/2f848e25ca383d9bb76fd60e8c7b0a4f) as there
was a lot of complexity, and I certainly could have made some errors in my
analysis.
Given these benchmark results, would the Go team reconsider such a language
feature on a basis of performance vs. a comparison of syntax to bring if
statement performance closer to that of switch statements? The current
disparity means developers must choose between the awkward single-case syntax
of switch statements and the more natural control flow of if statements, often
sacrificing either readability or performance.
I understand Go's philosophy of keeping the language small and orthogonal, but
this seems like a case where a targeted language feature could improve
performance for use-cases that needs it, or at least make the gaining that
performance much less awkward.
Thank you again for the consideration,
-Mike
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/golang-nuts/6C3EFB5F-B612-4FC6-B959-3A8255657483%40newclarity.net.