Slice can be simplified does not produce the same code
See original GitHub issueCurrently the IDE suggest with Span<T> not to use slice but instead use the Range indexer (IDE0057: Slice can be simplified to this). So the original code:
new Vector<T>(B.Slice(Idx))
is then translated to
new Vector<T>(B[Idx..])
the resulting generated code is different (which is OK)
public void WithSlice() {
ReadOnlySpan<float> A = new float[100];
for (int i=0; i<A.Length; i+= Vector<float>.Count)
new Vector<float>(A.Slice(i));
}
public void WithRange() {
ReadOnlySpan<float> A = new float[100];
for (int i=0; i<A.Length; i+= Vector<float>.Count)
new Vector<float>(A[i..]);
}
and the result taken from sharplab:
public void WithSlice()
{
ReadOnlySpan<float> readOnlySpan = new float[100];
for (int i = 0; i < readOnlySpan.Length; i += Vector<float>.Count)
{
new Vector<float>(readOnlySpan.Slice(i));
}
}
public void WithRange()
{
ReadOnlySpan<float> readOnlySpan = new float[100];
for (int i = 0; i < readOnlySpan.Length; i += Vector<float>.Count)
{
ReadOnlySpan<float> readOnlySpan2 = readOnlySpan;
int length = readOnlySpan2.Length;
int num = i;
int length2 = length - num;
new Vector<float>(readOnlySpan2.Slice(num, length2));
}
}
but the JIT Asm seems to be different. I didn’t make any performance comparisons, but for my environment it is crucial that the suggested rewrite does not alter the performance of the code.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:4
- Comments:9 (6 by maintainers)
Top Results From Across the Web
Code review: Can this be simplified? - JavaScript
I have an array with train journeys that I want to visualize in an svg. That is already working. Currently, some trains have...
Read more >object initialization can be simplified
The object initialization can be simplified messages may be useful in detecting points in your code where you can use a Creational Pattern,...
Read more >Go Slices: usage and internals
This article will look at what slices are and how they are used. ... they're a bit inflexible, so you don't see them...
Read more >Code Inspections in C# | ReSharper Documentation
Base member has 'params' parameter, but the overrider does not have it ... Dictionary lookup can be simplified with 'TryAdd'.
Read more >Experiment, Simplify, Ship
We'd write the same code for slices of bytes, and slices of strings, and so on. Our programs were too complex, because Go...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@svick The C# compiler and the types it’s generating use of are resulting in significantly more complex code for the JIT to then need to unwind. Such issues are covered by existing issues like https://github.com/dotnet/runtime/issues/11848 and https://github.com/dotnet/runtime/issues/11870. If this issue is about the JIT, it should just be closed.
That said, the C# compiler is doing a disservice here by using Slice(start, count) rather than just Slice(start). The latter has less code in it, less checks to be performed, and less code required to invoke it. I don’t know that the JIT would ever be able to make them identical; in theory it could, in practice that’s a whole lot of analysis. This was all raised when the indexing feature was introduced, and it was decided by the language team that such level of optimization wasn’t important.
If the analyzer from dotnet/roslyn is encouraging this transformation and folks expect the resulting code to be identical, then the dotnet/roslyn compiler should be updated to abide. There’s no guarantee the JIT will produce the same asm, otherwise.
I just wanted to point another benchmark on another system. I just wanted to point that there was a long way from coming from the “old” without-
Span<T>
world, where we did everything either in regular C#, going to unsafe code with pointer and then usingSpan<T>
and finally usingVector<T>
- Honestly thanks for the improvement in speed . The last method was a suggestion from @benaadams (thanks for that). One interesting finding is though that the AddVectorizedSpanWithRange is definitely slower on this example computer than on the first.Just for reference, here’s is the code: