{"action":"closed","issue":{"url":"https://api.github.com/repos/dotnet/corefx/issues/27786","repository_url":"https://api.github.com/repos/dotnet/corefx","labels_url":"https://api.github.com/repos/dotnet/corefx/issues/27786/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/27786/comments","events_url":"https://api.github.com/repos/dotnet/corefx/issues/27786/events","html_url":"https://github.com/dotnet/corefx/issues/27786","id":302832295,"number":27786,"title":"[Perf] XmlSerializer.Deserialize() regression between 2.0 and 2.1 for Linux (around 100%)","user":{"login":"adamsitnik","id":6011991,"avatar_url":"https://avatars2.githubusercontent.com/u/6011991?v=4","gravatar_id":"","url":"https://api.github.com/users/adamsitnik","html_url":"https://github.com/adamsitnik","followers_url":"https://api.github.com/users/adamsitnik/followers","following_url":"https://api.github.com/users/adamsitnik/following{/other_user}","gists_url":"https://api.github.com/users/adamsitnik/gists{/gist_id}","starred_url":"https://api.github.com/users/adamsitnik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adamsitnik/subscriptions","organizations_url":"https://api.github.com/users/adamsitnik/orgs","repos_url":"https://api.github.com/users/adamsitnik/repos","events_url":"https://api.github.com/users/adamsitnik/events{/privacy}","received_events_url":"https://api.github.com/users/adamsitnik/received_events","type":"User","site_admin":false},"labels":[{"id":882953167,"url":"https://api.github.com/repos/dotnet/corefx/labels/Post-ZBB","name":"Post-ZBB","color":"30c93a","default":false},{"id":192063576,"url":"https://api.github.com/repos/dotnet/corefx/labels/area-Serialization","name":"area-Serialization","color":"d4c5f9","default":false},{"id":849541036,"url":"https://api.github.com/repos/dotnet/corefx/labels/tenet-performance-benchmarks","name":"tenet-performance-benchmarks","color":"c2e0c6","default":false}],"state":"closed","locked":false,"assignee":{"login":"mconnew","id":8648390,"avatar_url":"https://avatars1.githubusercontent.com/u/8648390?v=4","gravatar_id":"","url":"https://api.github.com/users/mconnew","html_url":"https://github.com/mconnew","followers_url":"https://api.github.com/users/mconnew/followers","following_url":"https://api.github.com/users/mconnew/following{/other_user}","gists_url":"https://api.github.com/users/mconnew/gists{/gist_id}","starred_url":"https://api.github.com/users/mconnew/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mconnew/subscriptions","organizations_url":"https://api.github.com/users/mconnew/orgs","repos_url":"https://api.github.com/users/mconnew/repos","events_url":"https://api.github.com/users/mconnew/events{/privacy}","received_events_url":"https://api.github.com/users/mconnew/received_events","type":"User","site_admin":false},"assignees":[{"login":"mconnew","id":8648390,"avatar_url":"https://avatars1.githubusercontent.com/u/8648390?v=4","gravatar_id":"","url":"https://api.github.com/users/mconnew","html_url":"https://github.com/mconnew","followers_url":"https://api.github.com/users/mconnew/followers","following_url":"https://api.github.com/users/mconnew/following{/other_user}","gists_url":"https://api.github.com/users/mconnew/gists{/gist_id}","starred_url":"https://api.github.com/users/mconnew/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mconnew/subscriptions","organizations_url":"https://api.github.com/users/mconnew/orgs","repos_url":"https://api.github.com/users/mconnew/repos","events_url":"https://api.github.com/users/mconnew/events{/privacy}","received_events_url":"https://api.github.com/users/mconnew/received_events","type":"User","site_admin":false}],"milestone":{"url":"https://api.github.com/repos/dotnet/corefx/milestones/12","html_url":"https://github.com/dotnet/corefx/milestone/12","labels_url":"https://api.github.com/repos/dotnet/corefx/milestones/12/labels","id":2323293,"number":12,"title":"2.1.0","description":".NET Core 2.1, next major release. See [official release dates](https://github.com/dotnet/core/blob/master/roadmap.md) for details.","creator":{"login":"karelz","id":5776068,"avatar_url":"https://avatars2.githubusercontent.com/u/5776068?v=4","gravatar_id":"","url":"https://api.github.com/users/karelz","html_url":"https://github.com/karelz","followers_url":"https://api.github.com/users/karelz/followers","following_url":"https://api.github.com/users/karelz/following{/other_user}","gists_url":"https://api.github.com/users/karelz/gists{/gist_id}","starred_url":"https://api.github.com/users/karelz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/karelz/subscriptions","organizations_url":"https://api.github.com/users/karelz/orgs","repos_url":"https://api.github.com/users/karelz/repos","events_url":"https://api.github.com/users/karelz/events{/privacy}","received_events_url":"https://api.github.com/users/karelz/received_events","type":"User","site_admin":false},"open_issues":17,"closed_issues":7095,"state":"open","created_at":"2017-02-15T02:14:11Z","updated_at":"2018-05-01T00:09:58Z","due_on":null,"closed_at":null},"comments":4,"created_at":"2018-03-06T19:23:06Z","updated_at":"2018-05-01T00:09:58Z","closed_at":"2018-05-01T00:09:58Z","author_association":"MEMBER","body":"I have verified that the initial regression of 30% for Windows (#27636) was fixed by https://github.com/dotnet/coreclr/pull/16654 and https://github.com/dotnet/coreclr/pull/16659\r\n\r\nUnfortunately, this is not true for Linux (at least Ubuntu 16.04). `XmlSerializer.Deserialize()` is 100% slower for Linux, when comparing 2.0 and 2.1\r\n\r\nYou can use following code to reproduce the problem:\r\n\r\n```cs\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Diagnostics;\r\nusing System.IO;\r\nusing System.Linq;\r\nusing System.Runtime.CompilerServices;\r\nusing System.Xml.Serialization;\r\n\r\nnamespace XmlDeserializationRegression\r\n{\r\n    class Program\r\n    {\r\n        static void Main(string[] args)\r\n        {\r\n            var serializer = new XmlSerializer(typeof(LoginViewModel));\r\n            List<double> results = new List<double>();\r\n\r\n            using (var memoryStream = new MemoryStream(capacity: short.MaxValue))\r\n            {\r\n                serializer.Serialize(memoryStream, CreateLoginViewModel());\r\n\r\n                Benchmark(memoryStream, serializer, 1, \"Warmup\");\r\n\r\n                for (int i = 0; i < 10; i++)\r\n                {\r\n                    results.Add(RealRun(memoryStream, serializer, 1000, \"Actual run\"));\r\n                }\r\n            }\r\n\r\n            var coreclrAssemblyInfo = FileVersionInfo.GetVersionInfo(typeof(object).Assembly.Location);\r\n            var corefxAssemblyInfo = FileVersionInfo.GetVersionInfo(typeof(System.Text.RegularExpressions.Regex).Assembly.Location);\r\n\r\n            Console.WriteLine($\"CoreCLR {coreclrAssemblyInfo.FileVersion}, CoreFX {corefxAssemblyInfo.FileVersion}\");\r\n            Console.WriteLine($\"Avg: {results.Average()}, Min: {results.Min()}, Max: {results.Max()}\");\r\n        }\r\n\r\n        [MethodImpl(MethodImplOptions.NoInlining)]\r\n        private static double RealRun(Stream stream, XmlSerializer xmlSerializer, int invocationCount, string displayText) => Benchmark(stream, xmlSerializer, invocationCount, displayText);\r\n\r\n        private static double Benchmark(Stream stream, XmlSerializer xmlSerializer, int invocationCount, string displayText)\r\n        {\r\n            object deserialized = null;\r\n\r\n            GC.Collect();\r\n            GC.WaitForPendingFinalizers();\r\n            GC.Collect();\r\n\r\n            var timer = Stopwatch.StartNew();\r\n\r\n            for (int i = 0; i < invocationCount; i++)\r\n            {\r\n                stream.Position = 0;\r\n                deserialized = xmlSerializer.Deserialize(stream);\r\n            }\r\n\r\n            TimeSpan avg = timer.Elapsed / invocationCount;\r\n            Console.WriteLine($\"{displayText}: Average elapsed milliseconds: {avg.TotalMilliseconds}\");\r\n\r\n            GC.KeepAlive(deserialized);\r\n\r\n            return avg.TotalMilliseconds;\r\n        }\r\n\r\n        private static LoginViewModel CreateLoginViewModel()\r\n            => new LoginViewModel\r\n            {\r\n                Email = \"name.familyname@not.com\",\r\n                Password = \"abcdefgh123456!@\",\r\n                RememberMe = true\r\n            };\r\n    }\r\n\r\n    public class LoginViewModel\r\n    {\r\n        public string Email { get; set; }\r\n        public string Password { get; set; }\r\n        public bool RememberMe { get; set; }\r\n    }\r\n}\r\n```"}}
{"actor":{"display_login":"mconnew"}}