PageRenderTime 40ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/Python/Tests/Analysis/AnalysisTest.Perf.cs

https://gitlab.com/SplatoonModdingHub/PTVS
C# | 340 lines | 278 code | 41 blank | 21 comment | 17 complexity | 3c761f88c3975089a313c88a4fe87db2 MD5 | raw file
  1. // Python Tools for Visual Studio
  2. // Copyright(c) Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the License); you may not use
  6. // this file except in compliance with the License. You may obtain a copy of the
  7. // License at http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
  10. // OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
  11. // IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
  12. // MERCHANTABLITY OR NON-INFRINGEMENT.
  13. //
  14. // See the Apache Version 2.0 License for specific language governing
  15. // permissions and limitations under the License.
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Diagnostics;
  19. using System.IO;
  20. using System.Linq;
  21. using System.Text;
  22. using System.Threading;
  23. using Microsoft.PythonTools.Analysis;
  24. using Microsoft.PythonTools.Infrastructure;
  25. using Microsoft.PythonTools.Intellisense;
  26. using Microsoft.PythonTools.Interpreter;
  27. using Microsoft.PythonTools.Parsing;
  28. using Microsoft.PythonTools.Parsing.Ast;
  29. using Microsoft.Scripting;
  30. using Microsoft.VisualStudioTools;
  31. using TestUtilities;
  32. namespace AnalysisTests {
  33. public class FileStreamReader : StreamReader {
  34. public readonly string Path;
  35. public FileStreamReader(string filename)
  36. : base(filename) {
  37. Path = filename;
  38. }
  39. }
  40. public partial class AnalysisTest : BaseAnalysisTest {
  41. [PerfMethod]
  42. public void TestLookupPerf_Namespaces() {
  43. var entry = ProcessText(@"
  44. import System
  45. ");
  46. Stopwatch sw = new Stopwatch();
  47. sw.Start();
  48. for (int i = 0; i < 1000; i++) {
  49. foreach (var varRef in entry.GetMembersByIndex("System", 1)) {
  50. foreach (var innerRef in entry.GetMembersByIndex("System." + varRef.Name, 1)) {
  51. }
  52. }
  53. }
  54. sw.Stop();
  55. Console.WriteLine("{0} ms", sw.ElapsedMilliseconds);
  56. }
  57. [PerfMethod]
  58. public void TestParsePerf_Decimal() {
  59. string merlin = Environment.GetEnvironmentVariable("DLR_ROOT") ?? @"C:\Product\0\dlr";
  60. var text = File.ReadAllText(Path.Combine(merlin + @"\External.LCA_RESTRICTED\Languages\IronPython\27\Lib\decimal.py"));
  61. var sourceUnit = GetSourceUnit(text);
  62. var projectState = PythonAnalyzer.CreateSynchronously(InterpreterFactory, Interpreter);
  63. Stopwatch sw = new Stopwatch();
  64. var entry = projectState.AddModule("decimal", "decimal", null);
  65. Prepare(entry, sourceUnit);
  66. entry.Analyze(CancellationToken.None);
  67. sw.Start();
  68. for (int i = 0; i < 5; i++) {
  69. Prepare(entry, sourceUnit);
  70. entry.Analyze(CancellationToken.None);
  71. }
  72. sw.Stop();
  73. Console.WriteLine("{0}", sw.ElapsedMilliseconds);
  74. }
  75. [PerfMethod]
  76. public void TestLookupPerf_Modules_Class() {
  77. var entry = ProcessText(@"
  78. import System
  79. ");
  80. Stopwatch sw = new Stopwatch();
  81. sw.Start();
  82. #if IPY
  83. foreach (var result in entry.ProjectState.GetModuleMembers(new[] { "System", "IO", "BinaryReader" })) {
  84. }
  85. foreach (var result in entry.ProjectState.GetModuleMembers(new[] { "System", "IO", "BinaryWriter" })) {
  86. }
  87. foreach (var result in entry.ProjectState.GetModuleMembers(new[] { "System", "IO", "BufferedStream" })) {
  88. }
  89. foreach (var result in entry.ProjectState.GetModuleMembers(new[] { "System", "IO", "Stream" })) {
  90. }
  91. foreach (var result in entry.ProjectState.GetModuleMembers(new[] { "System", "IO", "Directory" })) {
  92. }
  93. foreach (var result in entry.ProjectState.GetModuleMembers(new[] { "System", "IO", "File" })) {
  94. }
  95. foreach (var result in entry.ProjectState.GetModuleMembers(new[] { "System", "IO", "FileStream" })) {
  96. }
  97. #endif
  98. sw.Stop();
  99. Console.WriteLine(sw.ElapsedMilliseconds);
  100. }
  101. [PerfMethod]
  102. public void TestLookupPerf_Namespaces2() {
  103. var entry = ProcessText(@"
  104. import System
  105. ");
  106. Stopwatch sw = new Stopwatch();
  107. sw.Start();
  108. foreach (var varRef in entry.GetMembersByIndex("System", 1)) {
  109. }
  110. foreach (var varRef in entry.GetMembersByIndex("System.Collections", 1)) {
  111. }
  112. foreach (var varRef in entry.GetMembersByIndex("System.Collections.Generic", 1)) {
  113. }
  114. foreach (var varRef in entry.GetMembersByIndex("System.CodeDom", 1)) {
  115. }
  116. foreach (var varRef in entry.GetMembersByIndex("System.Configuration", 1)) {
  117. }
  118. foreach (var varRef in entry.GetMembersByIndex("System.ComponentModel", 1)) {
  119. }
  120. foreach (var varRef in entry.GetMembersByIndex("System.Deployment", 1)) {
  121. }
  122. foreach (var varRef in entry.GetMembersByIndex("System.Diagnostics", 1)) {
  123. }
  124. foreach (var varRef in entry.GetMembersByIndex("System.Dynamic", 1)) {
  125. }
  126. foreach (var varRef in entry.GetMembersByIndex("System.Globalization", 1)) {
  127. }
  128. foreach (var varRef in entry.GetMembersByIndex("System.Linq", 1)) {
  129. }
  130. foreach (var varRef in entry.GetMembersByIndex("System.Management", 1)) {
  131. }
  132. foreach (var varRef in entry.GetMembersByIndex("System.Media", 1)) {
  133. }
  134. foreach (var varRef in entry.GetMembersByIndex("System.Net", 1)) {
  135. }
  136. foreach (var varRef in entry.GetMembersByIndex("System.Runtime", 1)) {
  137. }
  138. foreach (var varRef in entry.GetMembersByIndex("System.Security", 1)) {
  139. }
  140. foreach (var varRef in entry.GetMembersByIndex("System.Text", 1)) {
  141. }
  142. foreach (var varRef in entry.GetMembersByIndex("System.Threading", 1)) {
  143. }
  144. sw.Stop();
  145. Console.WriteLine("{0} ms", sw.ElapsedMilliseconds);
  146. }
  147. /// <summary>
  148. /// Gets all members from a large number of types
  149. /// </summary>
  150. [PerfMethod]
  151. public void TestLookupPerf_Types() {
  152. var entry = ProcessText(@"
  153. import System
  154. ");
  155. Stopwatch sw = new Stopwatch();
  156. sw.Start();
  157. foreach (var varRef in entry.GetMembersByIndex("System", 1)) {
  158. foreach (var innerRef in entry.GetMembersByIndex("System" + varRef.Name, 1)) {
  159. }
  160. }
  161. sw.Stop();
  162. Console.WriteLine("{0} ms", sw.ElapsedMilliseconds);
  163. }
  164. [PerfMethod]
  165. public void TestLookupPerf_BuiltinModules() {
  166. var builtin_module_names = new[] { "sys", "__builtin__", "exceptions", "clr", "future_builtins", "imp", "array", "binascii", "_sha512", "cmath", "_winreg", "_weakref", "_warnings", "_sre", "_random", "_functools", "xxsubtype", "time", "thread", "_struct", "_heapq", "_ctypes_test", "_ctypes", "socket", "_sha256", "_sha", "select", "re", "operator", "nt", "_md5", "_fileio", "math", "marshal", "_locale", "itertools", "gc", "errno", "datetime", "cStringIO", "cPickle", "copy_reg", "_collections", "_bytesio", "_codecs" };
  167. StringBuilder text = new StringBuilder();
  168. foreach (var name in builtin_module_names) {
  169. text.AppendLine("import " + name);
  170. }
  171. var entry = ProcessText(text.ToString());
  172. Stopwatch sw = new Stopwatch();
  173. sw.Start();
  174. for (int i = 0; i < 50; i++) {
  175. foreach (var name in builtin_module_names) {
  176. foreach (var varRef in entry.GetMembersByIndex(name, 1)) {
  177. foreach (var innerRef in entry.GetMembersByIndex(name + "." + varRef.Name, 1)) {
  178. }
  179. }
  180. }
  181. }
  182. sw.Stop();
  183. Console.WriteLine("{0} ms", sw.ElapsedMilliseconds);
  184. }
  185. internal PythonAnalyzer AnalyzeDir(string dir, PythonLanguageVersion version = PythonLanguageVersion.V27, IEnumerable<string> excludeDirectories = null, CancellationToken? cancel = null) {
  186. List<string> files = new List<string>();
  187. try {
  188. ISet<string> excluded = null;
  189. if (excludeDirectories != null) {
  190. excluded = new HashSet<string>(excludeDirectories, StringComparer.InvariantCultureIgnoreCase);
  191. }
  192. CollectFiles(dir, files, excluded);
  193. } catch (DirectoryNotFoundException) {
  194. return null;
  195. }
  196. List<FileStreamReader> sourceUnits = new List<FileStreamReader>();
  197. foreach (string file in files) {
  198. sourceUnits.Add(
  199. new FileStreamReader(file)
  200. );
  201. }
  202. Stopwatch sw = new Stopwatch();
  203. sw.Start();
  204. long start0 = sw.ElapsedMilliseconds;
  205. // Explicitly specify the builtins name because we are using a 2.7
  206. // interpreter for all versions.
  207. var fact = InterpreterFactoryCreator.CreateAnalysisInterpreterFactory(version.ToVersion());
  208. var projectState = new PythonAnalyzer(fact, fact.CreateInterpreter(), "__builtin__");
  209. projectState.ReloadModulesAsync().WaitAndUnwrapExceptions();
  210. projectState.Limits = AnalysisLimits.GetStandardLibraryLimits();
  211. var modules = new List<IPythonProjectEntry>();
  212. foreach (var sourceUnit in sourceUnits) {
  213. try {
  214. modules.Add(projectState.AddModule(
  215. ModulePath.FromFullPath(sourceUnit.Path).ModuleName,
  216. sourceUnit.Path,
  217. null
  218. ));
  219. } catch (ArgumentException) {
  220. // Invalid module name, so skip the module
  221. }
  222. }
  223. long start1 = sw.ElapsedMilliseconds;
  224. Trace.TraceInformation("AddSourceUnit: {0} ms", start1 - start0);
  225. var nodes = new List<Microsoft.PythonTools.Parsing.Ast.PythonAst>();
  226. for (int i = 0; i < modules.Count; i++) {
  227. PythonAst ast = null;
  228. try {
  229. var sourceUnit = sourceUnits[i];
  230. ast = Parser.CreateParser(sourceUnit, version).ParseFile();
  231. } catch (Exception) {
  232. }
  233. nodes.Add(ast);
  234. }
  235. long start2 = sw.ElapsedMilliseconds;
  236. Trace.TraceInformation("Parse: {0} ms", start2 - start1);
  237. for (int i = 0; i < modules.Count; i++) {
  238. var ast = nodes[i];
  239. if (ast != null) {
  240. modules[i].UpdateTree(ast, null);
  241. }
  242. }
  243. long start3 = sw.ElapsedMilliseconds;
  244. for (int i = 0; i < modules.Count; i++) {
  245. Trace.TraceInformation("Analyzing {1}: {0} ms", sw.ElapsedMilliseconds - start3, sourceUnits[i].Path);
  246. var ast = nodes[i];
  247. if (ast != null) {
  248. modules[i].Analyze(cancel ?? CancellationToken.None, true);
  249. }
  250. }
  251. if (modules.Count > 0) {
  252. Trace.TraceInformation("Analyzing queue");
  253. modules[0].AnalysisGroup.AnalyzeQueuedEntries(cancel ?? CancellationToken.None);
  254. }
  255. long start4 = sw.ElapsedMilliseconds;
  256. Trace.TraceInformation("Analyze: {0} ms", start4 - start3);
  257. return projectState;
  258. }
  259. internal sealed class FileTextContentProvider : TextContentProvider {
  260. private readonly FileStreamContentProvider _provider;
  261. public FileTextContentProvider(FileStreamContentProvider fileStreamContentProvider) {
  262. _provider = fileStreamContentProvider;
  263. }
  264. public override SourceCodeReader GetReader() {
  265. return new SourceCodeReader(new StreamReader(_provider.GetStream(), Encoding.ASCII), Encoding.ASCII);
  266. }
  267. }
  268. internal sealed class FileStreamContentProvider : StreamContentProvider {
  269. private readonly string _path;
  270. internal string Path {
  271. get { return _path; }
  272. }
  273. #region Construction
  274. internal FileStreamContentProvider(string path) {
  275. _path = path;
  276. }
  277. #endregion
  278. public override Stream GetStream() {
  279. return new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.Read);
  280. }
  281. }
  282. private static void CollectFiles(string dir, List<string> files, ISet<string> excludeDirectories = null) {
  283. foreach (string file in Directory.GetFiles(dir)) {
  284. if (file.EndsWith(".py", StringComparison.OrdinalIgnoreCase)) {
  285. files.Add(file);
  286. }
  287. }
  288. foreach (string nestedDir in Directory.GetDirectories(dir)) {
  289. if (excludeDirectories != null) {
  290. var dirName = Path.GetFileName(nestedDir);
  291. if (excludeDirectories.Contains(dirName)) {
  292. continue;
  293. }
  294. }
  295. CollectFiles(nestedDir, files, excludeDirectories);
  296. }
  297. }
  298. }
  299. }