-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
[Wasm][AOT] Performance regression in List<string> foreach #54272
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
Tagging subscribers to 'arch-wasm': @lewing Issue DetailsDescriptionA performance regression happened when using this repro (with var SUT = new List<object>();
SUT.AddRange(Enumerable.Range(1, 1000)
.Select(i => (object)null));
var sw = Stopwatch.StartNew();
for (int i = 0; i < 5000; i++)
{
int count = 0;
foreach (var item in SUT)
{
count++;
}
}
sw.Stop();
Console.WriteLine($"TestForeachListOfT: {sw.Elapsed}"); Some performance benchmarks: With df6e956: With a822d39: With d07f911 and 337216a: ConfigurationRegression?Yes Other information
|
This should be fixed by |
Here's the perf numbers, with 881e902: TestForeachListOfT: 00:00:00.3946000 Still with |
What is the issue here ? Is it that foreach on a list is slower than a for loop or a for loop on an array ? |
The issue is that the foreach loop is calling into interpreted code, where as the for loop is not. When the code in the method is AOTed, it's 3x faster than the interpreted one (see the flame chart for a822d39 above). |
Here's the full sample I'm running: static void Main(string[] args)
{
TestEnumeratorListOfT();
TestForeachListOfT();
TestForListOfT();
TestForArray();
}
private static void TestForArray()
{
var SUT = new List<object>();
SUT.AddRange(Enumerable.Range(1, 1000)
.Select(i => (object)null));
var SUT2 = SUT.ToArray();
var sw = Stopwatch.StartNew();
for (int i = 0; i < 5000; i++)
{
int count = 0;
foreach (var item in SUT2)
{
count++;
}
}
sw.Stop();
Console.WriteLine($"TestForArray: {sw.Elapsed}");
}
private static void TestForListOfT()
{
var SUT = new List<object>();
SUT.AddRange(Enumerable.Range(1, 1000)
.Select(i => (object)null));
var sw = Stopwatch.StartNew();
for (int j = 0; j < 5000; j++)
{
int count = 0;
for (int i = 0; i < SUT.Count; i++)
{
var r = SUT[i];
count++;
}
}
sw.Stop();
Console.WriteLine($"TestForListOfT: {sw.Elapsed}");
}
private static void TestForeachListOfT()
{
var SUT = new List<object>();
SUT.AddRange(Enumerable.Range(1, 1000)
.Select(i => (object)null));
var sw = Stopwatch.StartNew();
for (int i = 0; i < 5000; i++)
{
int count = 0;
foreach (var item in SUT)
{
count++;
}
}
sw.Stop();
Console.WriteLine($"TestForeachListOfT: {sw.Elapsed}");
}
private static void TestEnumeratorListOfT()
{
var SUT = new List<object>();
SUT.AddRange(Enumerable.Range(1, 1000)
.Select(i => (object)null));
var sw = Stopwatch.StartNew();
for (int i = 0; i < 5000; i++)
{
int count = 0;
var enumerator = SUT.GetEnumerator();
while (enumerator.MoveNext())
{
var r = enumerator.Current;
count++;
}
}
sw.Stop();
Console.WriteLine($"TestEnumeratorListOfT: {sw.Elapsed}");
} |
I reran the sample above with e983168, and here are the results:
|
This behavior was caused by a rogue Thanks @vargaz for the troubleshooting. |
Description
A performance regression happened when using this repro (with
-O=gsharedvt
formono-aot-cross
):Some performance benchmarks:
With df6e956:
Result:
TestForeachListOfT: 00:00:00.3979650
With a822d39:
Result:
TestForeachListOfT: 00:00:00.1164150
With d07f911 and 337216a:
Result:
TestForeachListOfT: 00:00:00.2462100
Configuration
Regression?
Yes
Other information
The text was updated successfully, but these errors were encountered: