-
Notifications
You must be signed in to change notification settings - Fork 349
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
chapter2: switch O(n) #31
Comments
Half the issue would be go's duck typing, wouldn't it? Since any type can fulfil any interface implicitly, you'd need to manually check each one. |
@neetle I don't follow... Yes, any type can be passed to the switch, and if that is not one of the expected types the hash function would simply transform its hash to one of the indices. Then you'd jump to the given case, compare actual type (which you need to do anyway because of collisions on the 'original' hash) and jump to the default branch if it's not matching. |
This thing is just like "cascaded" |
I agree with you when it comes to things like func foo(x interface{}) {
switch x.(type) {
case io.Reader:
// normal interfaces
case interface {
io.Writer
CanBar() bool
}:
// embedded interfaces
case struct { Baz string `tag:"value"` }:
// anon struct matching
}
} For values of As an aside, I'm not sure the hash-lookup strategy would even be worth the cost of entry. |
@neetle OK, I was not aware that you can do embedded interfaces/anon struct matching like the above. The assembly for that would probably look quite different to the one shown in the chapter. The simple matching is probably too niche to be worth the optimization. I agree that there would probably need to be a threshold to go for any 'smarter' strategy, and that should be set based on experimental evidence; I just assumed that given that arithmetic operations as those performed by common hashing functions are cheap enough. |
No problem! Most people don't consider the pathological case that our more "inspired" coworkers take. As an aside - the struct doesn't need to be anon & inline to match, it just needs to have the same fields in the same order with the same tags iirc. If we were to drift into theorising land, I'd argue that a better strategy would be to use something more akin to bloom trees. The "perfect hash" for them could be calculated at compile time, along with the bloom tree itself. Following that, it's just a "make sure it's where we think it is". In saying that though, that could be expensive, unwieldy and the possible interactions with reflection make me want to gag. Also, my compsci skills are non-existent so take this last portion with a mountain of salt. |
I actually got surprised that type switches are O(N).
I would assume that since the list of hashes is known at compile time, the compiler could find a perfect hashing function and just do a few arithmetic ops to get the address on which to jump1. At least if the size of switch exceeds some threshold.
If finding perfect hash would be too time-consuming, it could at least sort the hashes and do a binary search.
I guess the answer is that this is one of the optimizations Go is still awaiting...
EDIT: 1 Actually it would need to get just an index and lookup the target address; compiler knows the list of target hashes but not all input hashes.
The text was updated successfully, but these errors were encountered: