-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Reduce allocations in TableWriter #6648
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
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here,
alignmentis passed to another methodGenerateRow, so it's not safe to usestackallochere.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks to me that
GenerateRowusesalignmentbefore this function returns and therefore should be safe.Additionally, if the compiler can detect this condition as the blog suggests (per @iSazonov's comment), then we should rely on the compiler's analysis unless we find the compiler's analysis deficient.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should add that Span<T> is managed code.
Before C# 7.2 we have some protections for Span<T> only in runtime.
Since C# 7.2 Roslyn does additional checks at compile time and exclude unapproved usage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand the C# compiler can catch an issue like that, but the person who is facing that compilation error might not be the one who used
stackallocin the first place.Imagine I will change the implementation of
GenerateRowat some later time and my change would actually cause the unsafe reference to happen, and that means I will see the compilation error but have no idea why it fails. After finally figuring out why this could happen, I will need to search all callers of this methods and maybe the callers of those callers and so on to find "Ah, there is a stackalloc here".Therefore, I think we should have a guideline about when to use
stackalloc, so things can be less complex.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the error might be confusing to another contributor.
If we have guidance on when
spanandstackalloccan be used it should be clear and easy to follow.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SteveL-MSFT They don't support Alpine in 2.0 and support in 2.1 Prview1 and perhaps in Preview2
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you didn't get my point.
What I try to point out is the use of
stackallocmight make future changes raise compilation error at an unexpected location.Use the same example, say initially methods
MethodOneandMethodTwolooked like this:So when you changed to use
stackallocinMethodOne, it would compiles fine, and the methods became:Then later, another contributor changes
MethodTwoto return a sclice of the pass-in argumentspanlike this:And then the contributor will see the unexpected compilation error from
MethodOne.This is the situation that I want to avoid with some coding guidelines. So what should be the guideline in this situation? Should it be:
MehtodTwo)MethodOne)Hope I made myself clear this time :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see your point. I believe we could compare this with changing in a base class - we can catch tons compilation errors in derived classes - this is the same situation. Another example is a changing in a helper class - we can get compilation errors in each call point.
And it seems like your example is too incredible if we try to imagine a real situation - such a change in the code completely changes its contract as if
Array. Sortwould start to do aclone-then-sort. By the way, in the latter case we may get an unpredictable run-time error or nothing worse. So Span gives even more reliable code.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is something that we will have to get used to. It is a new and very welcome addition to the .net runtime, and we as developers need to learn to troubleshoot the issues that arises.
I say let the compilation error happen, and add answers to StackOverflow on how to resolve and understand them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we use a threshold to select
stackallocvsnewwe could use one of two patternshttps://github.com/dotnet/corefx/blob/58af9adc8c6c70df4b7fd158c984508d96baca59/src/Common/src/System/Security/Cryptography/ECDiffieHellmanOpenSsl.Derive.cs#L165
https://github.com/dotnet/corefx/blob/8b70122cef4a165def5224001b38f10967619669/src/Common/src/CoreLib/System/Globalization/CompareInfo.Windows.cs#L141
Also I found interesting sample https://github.com/dotnet/corefx/blob/fcfb556ebf99ed551c02d0146c805e792b264cf2/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemName.cs#L197 - using
Span<int> temp = stackalloc int[0];disable expose outside of the method.