-
Notifications
You must be signed in to change notification settings - Fork 21
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
Allow for int64 and bigints in indexed for loops #876
Comments
This comment has been minimized.
This comment has been minimized.
I'm sure he meant:
The range version |
Fixed Yes, the current form allocates and uses an enumerator, which results in about a 6x performance degradation compared to a loop or tail recursive function. Note that, as is often the case in F#, some compiler trickery is played and when using ints the enumerator stuff gets optimized away. But not with longs or bigints. |
Implementation-wise I assume this would mean using
The allocation cost is amortized away with increasing iteration count, no? If you're going to use many short-lived for loops, you don't need support for larger ranges in the first place. Of course, each iteration is faster when you don't have to use the enumerator, so that would still be a win for tight loops with billions of iterations. |
Yes. Instead, It is the overhead of a non-inlineable method call that is the actual cost here. A simple Implementation-wise, as long as the value of the iteration is not used, this could be implemented with Though more likely than not, a user choosing |
This could only work if start and finish were constants. Otherwise you can't tell at compile time if the range fits into an int32.
You mean in the body of the loop? You might as well use int32 in the loop and then convert it to a biginteger. Shouldn't be any slower than having bigintegers in the loop (without an enumerator, that is), incremented in the background. |
It doesn’t have to fit. But you’re right, the extra checks and corner cases that arise are probably not worth the effort.
Not sure. That depends on how But thinking again about that approach, I wonder if it’s worth the effort. If a programmer wants speed over convenience, they’d like use some way of double nested |
One option would be to treat I have tried this out locally and it does indeed work. A couple of callouts:
|
The I am not sure I like universally treating |
Right, I guess it depends whether this suggestion was really more about (1) applying the optimizations that existed at the time for for-loops but not for for-each loops to more types, or (2) allowing more types to use the for-loop syntax. I would say that even though we have solved (1) for
I don't think there would be any performance impact on any existing code, since for-loops currently only allow
We would need to default to let f x y = for n = x to y do … I can't think of any other interactions this would have with tooling, though, since, again, the same syntax is already supported in computation expressions with any type. The only question I would have would be what error message to show if we disallowed unsigned types with |
@T-Gro This is what I meant: dotnet/fsharp#18301. |
Ok that makes sense - you still try |
Title of Suggestion
I propose we allow for loops of the following form:
The existing way of approaching this problem in F# is to use the
in..do
syntax:Though this does make some things awkward because the indexer style may be preferred in some situations.
Pros and Cons
The advantages of making this adjustment to F# are:
The disadvantages of making this adjustment to F# are:
Extra information
These kinds of loops work in C#, so it's certainly possible to also allow them in F#.
Estimated cost (XS, S, M, L, XL, XXL): S-M
Related suggestions: #55
Affidavit (please submit!)
Please tick this by placing a cross in the box:
Please tick all that apply:
The text was updated successfully, but these errors were encountered: