-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
in
operator is O(n)
#277
Comments
@lutherwenxu |
AFAIK, operators overloading is not planned in V. In my opinion, the
|
@MrOnlineCoder: Allowing O(n) in for arrays but not O(k) in for maps seems misguided. If we have in it must be overloadable. Choosing to use a.contains(v) means the programmer has to think about which function to use, perhaps choosing to use e.g. a binary search instead if in a tight loop. |
|
@Delta456 that commit isn't relevant |
I think you meant b242e8d. That commit just does loop unrolling for a literal array. in is still O(n) on a runtime array. |
@ntrel my bad.. |
An interesting thing about it is that the linear algorithm is actually significantly faster for a small N. In Ruby they recently changed their maps to use arrays for N < 10 (or 40, can't find the commit). So For large arrays it should be clear that |
Yes, I know. I've explained above why it's bad to encourage using an operator. |
For static arrays and non-mut arrays this cane be made O(1) - see #6991 (comment) . Probably worth for arrays of cumulative size bigger than few cache line sizes. |
Only when the initializer is known at compile time. |
@ntrel of course - I was myself surprised how often is that the case. |
Hi, to summarize everything that is going on here:
My thoughts:
I decided to close this issue because of:
If you think this issue still needs to be open - feel free to reopen it with a comment on why you decided to do so. |
I do not want to reopen but I would like to understand why static arrays should not use perfect hashing by default. Perfect hashing does the same thing as jumping to an index. V arrays do bounds checking for plain C arrays. An So why not default? Is there even a single disadvantage (we do not speak of extreme - yet common - cases as e.g. very short arrays of less than ~32 octets)? |
Btw. for non-static arrays of fixed-sized items (e.g. integers, floats, all structs, fixed-length strings, etc.) there are also nice trivial optimizations possible like the limit branching in a tight loop by halving the number of comparisons (works also for tiny arrays). This should be a no-brainer. |
I don't have a lot of experience in this area, but right now I see 2 disadvantages of converting a static array into a hash map by default:
I'm also not sure if Clang/GCC already does that kind of optimization. I found no info about that. If you think this still should be a case - please, create a new issue, and maybe more experienced people in optimizations than me will leave a comment on this. |
Interesting concept, but unfortunately:
In the production build (Clang), the new algorithm is after about 17% which can be handy. I will open a new issue about that. If you want to review/retest my code, here it is -> https://pastebin.com/mvRLWNYs
|
Created issue -> #18283 |
I see. Thanks for bringing this up. This is actually a misnomer as e.g.
Yes and no 😉. Memory usage is totally different from normal mutable/immutable arrays (the difference seems easily being higher tens of percent especially in case of small size arrays). Shall we mark this also somewhere? If not, then why not to allow the memory usage be again closer to non-static arrays? Btw. "optimize with hash table" would be overly misleading IMHO (it even sounds a little like an oxymoron). Beware that e.g. What I did not check is the iteration performance over
AFAIK they do not and there seem to be no plans to do so. It is too high-level for them IMHO.
I think so, but my situation does not allow me to devote much time to this. Could you at least document it that it is a known pitfall and subject to change before |
https://vlang.io/docs#in
This operator does a linear search through an array taking O(n) time. Building it into the language with special short syntax encourages programmers to reach for that instead of considering what other functions they might use.
Instead of encouraging use of this operation, a method would be clearer:
[v1, v2, v3].contains(item)
V should be able to know that the array literal does not escape the function call and allocate it on the stack. This is a good general optimization rather than just for linear find.
BTW for containers like maps that have better than O(n) search, having an
in
operator would be OK. This meansin
needs to be overloadable.The text was updated successfully, but these errors were encountered: