-
Notifications
You must be signed in to change notification settings - Fork 5k
Fix LINQ handling of iterator.Take(...).Last(...) #112680
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,8 +31,8 @@ private static void SameResultsWithQueryAndRepeatCallsWorker<T>(IEnumerable<T> f | |
first = from item in first select item; | ||
second = from item in second select item; | ||
|
||
VerifyEqualsWorker(first.Concat(second), first.Concat(second)); | ||
VerifyEqualsWorker(second.Concat(first), second.Concat(first)); | ||
Assert.Equal(first.Concat(second), first.Concat(second)); | ||
Assert.Equal(second.Concat(first), second.Concat(first)); | ||
} | ||
|
||
[Theory] | ||
|
@@ -41,8 +41,8 @@ private static void SameResultsWithQueryAndRepeatCallsWorker<T>(IEnumerable<T> f | |
[InlineData(new int[] { 2, 3, 5, 9 }, new int[] { 8, 10 }, new int[] { 2, 3, 5, 9, 8, 10 })] // Neither side is empty | ||
public void PossiblyEmptyInputs(IEnumerable<int> first, IEnumerable<int> second, IEnumerable<int> expected) | ||
{ | ||
VerifyEqualsWorker(expected, first.Concat(second)); | ||
VerifyEqualsWorker(expected.Skip(first.Count()).Concat(expected.Take(first.Count())), second.Concat(first)); // Swap the inputs around | ||
Assert.Equal(expected, first.Concat(second)); | ||
Assert.Equal(expected.Skip(first.Count()).Concat(expected.Take(first.Count())), second.Concat(first)); // Swap the inputs around | ||
} | ||
|
||
[Fact] | ||
|
@@ -80,7 +80,7 @@ public void SecondNull() | |
public void VerifyEquals(IEnumerable<int> expected, IEnumerable<int> actual) | ||
{ | ||
// workaround: xUnit type inference doesn't work if the input type is not T (like IEnumerable<T>) | ||
VerifyEqualsWorker(expected, actual); | ||
Assert.Equal(expected, actual); | ||
} | ||
|
||
[Theory] | ||
|
@@ -133,23 +133,6 @@ public void First_Last_ElementAt(IEnumerable<int> _, IEnumerable<int> actual) | |
} | ||
} | ||
|
||
private static void VerifyEqualsWorker<T>(IEnumerable<T> expected, IEnumerable<T> actual) | ||
{ | ||
// Returns a list of functions that, when applied to enumerable, should return | ||
// another one that has equivalent contents. | ||
var identityTransforms = IdentityTransforms<T>(); | ||
|
||
// We run the transforms N^2 times, by testing all transforms | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm puzzled by the purpose this method, it all seems entirely unnecessary. Am I missing something? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The purpose of the method I deleted because it served no worthwhile purpose? :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah. I'm legitimately curious about what motivated its inclusion back then. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Misguided, I think. The stated intent is to validate that all transformations are equivalent to all other transformations, but that doesn't require N^2 tests, and we also don't need to test the test transformations themselves. I guess it didn't hurt much when it was fast because there were only a few transformations, but my change causes N to grow from 13 to 1099, which means N^2 grows from 169 to 1,207,801... and that difference is very noticeable :) |
||
// of expected against all transforms of actual. | ||
foreach (var outTransform in identityTransforms) | ||
{ | ||
foreach (var inTransform in identityTransforms) | ||
{ | ||
Assert.Equal(outTransform(expected), inTransform(actual)); | ||
} | ||
} | ||
} | ||
|
||
public static IEnumerable<object[]> ArraySourcesData() => GenerateSourcesData(outerTransform: e => e.ToArray()); | ||
|
||
public static IEnumerable<object[]> SelectArraySourcesData() => GenerateSourcesData(outerTransform: e => e.Select(i => i).ToArray()); | ||
|
@@ -292,7 +275,7 @@ public void ManyConcats(IEnumerable<IEnumerable<int>> sources) | |
} | ||
|
||
Assert.Equal(sources.Sum(s => s.Count()), concatee.Count()); | ||
VerifyEqualsWorker(sources.SelectMany(s => s), concatee); | ||
Assert.Equal(sources.SelectMany(s => s), concatee); | ||
} | ||
} | ||
|
||
|
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.
Here we miss a fast path if count != -1 but count <= _minIndexInclusive.
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.
The purpose of this change is to fix a bug. I don't want to add additional optimizations as part of it. Please feel free to submit a follow-up PR after this goes in.