Example #1
0
		public PerfStat this[string key]
		{
			get
			{
				PerfStat counter;
				if (_stats.TryGetValue(key, out counter) == false)
				{
					counter = new PerfStat(key);
					_stats[key] = counter;
				}
				return counter;
			}
		}
Example #2
0
        static int Main(string[] args)
        {
            Console.Error.WriteLine();
            Console.Error.WriteLine(string.Format("{0} - Command Line Profiler", Name));
            Console.Error.WriteLine("Mark Gillard, 2016 | [email protected] | marzersoft.com");
            Console.Error.WriteLine();

            string exe = "", exeArgs = "", desc = "";
            bool csv = false;

            //parse arguments
            {
                ArgData value = null, key = null;
                for (int i = 0; i < args.Length; i++)
                {
                    key = value ?? new ArgData(args[i]);
                    value = i < args.Length - 1 ? new ArgData(args[i + 1]) : null;

                    if (!key.IsFlag || key.Handled)
                        continue;

                    //single-token flags
                    if (key.Handled = (key.Value == "?"))
                    {
                        Console.Error.WriteLine(Help);
                        return 0;
                    }
                    else if (key.Handled = (key.Value == "csv"))
                        csv = true;

                    //key-value pairs
                    else if (value != null && !value.IsFlag)
                    {
                        if (key.Handled = value.Handled = (key.Value == "exe"))
                            exe = value.Value;
                        else if (key.Handled = value.Handled = (key.Value == "args"))
                            exeArgs = value.Value;
                        else if (key.Handled = value.Handled = (key.Value == "desc"))
                            desc = value.Value.Replace(',',' ').Replace('\t',' ').Trim();
                    }
                }
            }

            //check exe
            if (exe.Length == 0)
            {
                Console.Error.WriteLine("No executable specified");
                Console.Error.WriteLine();
                Console.Error.WriteLine(Usage);
                return 1;
            }
            if (!Path.HasExtension(exe))
                exe += ".exe";
            if (!File.Exists(exe))
            {
                Console.Error.WriteLine("Specified executable {0} could not be found", exe);
                Console.Error.WriteLine();
                Console.Error.WriteLine(Usage);
                return 2;
            }

            //set up performance counter
            PerformanceCounter cpuCounter = new PerformanceCounter(
                "Processor",
                "% Processor Time",
                "_Total",
                true
            );
            double totalRam = (new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory / (1024ul * 1024ul));
            PerformanceCounter ramCounter = new PerformanceCounter("Memory", "Available MBytes", true);

            //execute command
            if (!csv)
            {
                Console.Out.WriteLine("Executing {0}", desc.Length == 0 ? "process" : "\"" + desc + "\"");
                Console.Out.WriteLine("({0} {1})", exe, exeArgs);
                Console.Out.WriteLine("----");
            }
            Timer timer = new Timer();
            double executionTime = 0.0;
            Process proc = null;
            try
            {
                proc = Process.Start(new ProcessStartInfo()
                {
                    CreateNoWindow = true,
                    UseShellExecute = false,
                    RedirectStandardError = true,
                    RedirectStandardOutput = true,
                    WindowStyle = ProcessWindowStyle.Hidden,
                    FileName = Path.GetFullPath(exe),
                    Arguments = exeArgs
                });
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("{0} thrown while launching executable ({1})", e.GetType().Name, e.Message);
                return 3;
            }
            proc.Exited += (sender, e) => { executionTime = timer.Stopwatch; };

            //spawn process monitoring thread
            Thread monitor;
            List<PerfNode> perfNodes = new List<PerfNode>();
            (monitor = new Thread(() =>
            {
                proc.Refresh();
                while (!proc.HasExited)
                {
                    perfNodes.Add(new PerfNode(proc, ramCounter, cpuCounter));
                    Thread.Sleep(125);
                    proc.Refresh();
                }
            })
            { Priority = ThreadPriority.AboveNormal }).Start();

            //spawn io redirection threads
            Thread stderr = null, stdout = null;
            (stdout = new Thread(() =>
            {
                if (csv) //redirect stdout to stderr to avoid polluting csv output
                    Console.Error.Write(proc.StandardOutput.ReadToEnd());
                else
                    Console.Out.Write(proc.StandardOutput.ReadToEnd());
                proc.WaitForExit();
            })
            { Priority = ThreadPriority.BelowNormal }).Start();
            (stderr = new Thread(() =>
            {
                Console.Error.Write(proc.StandardError.ReadToEnd());
                proc.WaitForExit();
            })
            { Priority = ThreadPriority.BelowNormal }).Start();

            //wait for threads to finish
            stdout.Join();
            stderr.Join();
            monitor.Join();

            //report execution stats
            if (csv)
            {
                Console.Out.Write("{0}", desc.Length == 0 ? Path.GetFileName(exe) : desc);
                Console.Out.Write(",\t{0}", executionTime);
                Console.Out.Write(",\t{0}", totalRam);
            }
            else
            {
                Console.Out.WriteLine("----");
                Console.Out.WriteLine("Child process finished.");
                Console.Out.WriteLine("Time taken: {0} s", executionTime);
                Console.Out.WriteLine("Samples recorded: {0}", perfNodes.Count);
                Console.Out.WriteLine("Total System Memory: {0} Mb", totalRam);
            }

            //report individual metrics
            PerfStat processRam = new PerfStat("Process Memory Usage");
            PerfStat systemRam = new PerfStat("System Memory Usage");
            PerfStat systemCpu = new PerfStat("System CPU Percentage");
            foreach (PerfNode node in perfNodes)
            {
                processRam.Add(node.PrivateMemory);
                systemRam.Add(totalRam - node.SystemMemory);
                systemCpu.Add(node.CpuPercentage);
            }
            if (csv)
            {
                Console.Out.Write(",\t{0}", processRam.ToCSV("0.00", 1.0 / (1024.0 * 1024.0)));
                Console.Out.Write(",\t{0}", systemRam.ToCSV("0.00", 1.0));
                Console.Out.Write(",\t{0}", systemCpu.ToCSV("0.00"));
            }
            else
            {
                Console.Out.WriteLine(processRam.ToString(" Mb", "0.00", 1.0 / (1024.0 * 1024.0), totalRam));
                Console.Out.WriteLine(systemRam.ToString(" Mb", "0.00", 1.0, totalRam));
                Console.Out.WriteLine(systemCpu.ToString(" %", "0.00"));
                Console.Out.WriteLine("");
            }
            return 0;
        }