> On Mar 18, 2025, at 8:40 PM, Ian Lance Taylor <i...@golang.org> wrote:
> 
> On Tue, Mar 18, 2025 at 4:51 PM Mike Schinkel <m...@newclarity.net> 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 golang-nuts+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/golang-nuts/6C3EFB5F-B612-4FC6-B959-3A8255657483%40newclarity.net.

Reply via email to