Как найти счетчик в программе

Loony

Искусственный Интеллект

(615365)


9 лет назад

Делается это так: до того, как программа ставилась в первый раз, перед установкой делается снимок реестра, потом программа устанавливается и делается второй снимок. Потом, смотрится, какие ключи были записаны в реестр. Вот, среди них и ищут нужные ключи, причем, очень часто, никоим образом их название не совпадает с названием программы. Всё это можно сделать при помощи RegOrganizer.

Если программа уже установлена, то придётся запускать монитор реестра и долго и нудно отслеживать. Многое зависит от опыта и “хитрости” программеров, которые писали защиту.

Можно поставить виртуальную ось и там всё это проделывать.

После того, как нужное найдено, пишется REG-файл, который обнуляет эти счётчики. Это, самый простой этап.

Источник: Личный опыт

# Ded PilulkiN #

Искусственный Интеллект

(468208)


9 лет назад

Registry Trash Keys Finder ( TrashReg) — это особый инструмент для чистки Реестра. Главное предназначение программы — это удаление ключей Реестра Windows, ставших уже ненужными для Вашей операционной системы. Многие программы оставляют в Реестре созданные ими ключи, причем даже после использования специальных деинсталляторов, поставляемых с этими же программами. RTKF позволяет Вам самим решать, стоит ли оставить найденные ключи, или их следует удалить.
Дополнительным эффектом такой очистки Реестра (и это может оказаться для некоторых пользователей главной целью использования программы) является продление срока ознакомительного использования некоторых программ, имеющих ограничения по времени их работы или/и по числу запусков (триал версий) .
Тем не менее, RTKF — это никакой не “крек”, а всего лишь небольшое дополнение к другому реестроочистительному программному обеспечению.

0 / 0 / 0

Регистрация: 17.07.2015

Сообщений: 4

1

Как реализовать счётчик дней?

17.07.2015, 13:54. Показов 2275. Ответов 7


Студворк — интернет-сервис помощи студентам

доброго времени суток !
обращаюсь с следующим вопросом : в C# Windows Forms (Visual Studio 2013)
нужно написать счетчик дней
что бы каждый день он прибавлял 1н день !
и кнопку , для обнуления …
есть идеи , как это реализовать ?!
(путной информации так и не нашел на просторах инета)



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

17.07.2015, 13:54

7

OwenGlendower

Администратор

Эксперт .NET

15537 / 12518 / 4977

Регистрация: 17.03.2014

Сообщений: 25,390

Записей в блоге: 1

17.07.2015, 15:36

2

Лучший ответ Сообщение было отмечено tezaurismosis как решение

Решение

Sirius101, 1) открываешь файл PropertiesSettings.settings

2) Добавляешь параметр с именем runDate, типом DateTime и Scope = User. Выставь ему значение текущей даты.

3) В коде события Load формы пишешь:

C#
1
labelDays.Text = string.Format("Кол-во прошедших дней: {0}", (DateTime.Today - Properties.Settings.Default.runDate.Date).Days));

4) В коде кнопки Reset пишешь:

C#
1
2
Properties.Settings.Default.runDate = DateTime.Now;
Properties.Settings.Default.Save();

Добавлено через 31 минуту
Вдогонку. Данный код обновляет кол-во прошедших дней только при запуске. Если необходимо чтобы кол-во дней могло меняться во время работы приложения, то добавь таймер.



1



0 / 0 / 0

Регистрация: 17.07.2015

Сообщений: 4

18.07.2015, 13:50

 [ТС]

3

Это сработало …но не совсем так , как хотелось .
программа обновляет данные в счетчике только при запуске …
а нужно постоянное обновление связанное с изменением даты



0



Администратор

Эксперт .NET

15537 / 12518 / 4977

Регистрация: 17.03.2014

Сообщений: 25,390

Записей в блоге: 1

18.07.2015, 13:59

4

Цитата
Сообщение от Sirius101
Посмотреть сообщение

программа обновляет данные в счетчике только при запуске …

Я знаю.

Цитата
Сообщение от Sirius101
Посмотреть сообщение

а нужно постоянное обновление связанное с изменением даты

Уже писал выше – используй таймер.



0



0 / 0 / 0

Регистрация: 17.07.2015

Сообщений: 4

18.07.2015, 14:48

 [ТС]

5

Относительно недавно занялся изучением C#
не сталкивался раньше с таймером …..

Добавлено через 24 секунды
просто вставить весь исполняемый код в это событие , не ?!



0



Администратор

Эксперт .NET

15537 / 12518 / 4977

Регистрация: 17.03.2014

Сообщений: 25,390

Записей в блоге: 1

19.07.2015, 00:41

6

Цитата
Сообщение от Sirius101
Посмотреть сообщение

просто вставить весь исполняемый код в это событие , не ?!

Весь не надо Достаточно одной строки кода которую я советовал написать в обработчике события Load. Есть еще смысл добавить проверку что кол-во дней в самом деле отличается чтобы не обновлять зря UI. Также советую устанвливать интервал для таймера побольше. Например, раз в час если до полуночи далеко, а при приближении к ней уменьшать интервал. Таким образом мы будем уменьшать нагрузку на систему в целом.



1



0 / 0 / 0

Регистрация: 17.07.2015

Сообщений: 4

21.07.2015, 14:01

 [ТС]

7

все заработало , все обновляет )
но обнаружен баг ! )
кнопка “ресет” сбрасывает не до нуля а до 1цы в промежутке от 00 до 4х утра !
Дальше обнуление происходит штатно
есть идеи , о причинах ?



0



Администратор

Эксперт .NET

15537 / 12518 / 4977

Регистрация: 17.03.2014

Сообщений: 25,390

Записей в блоге: 1

21.07.2015, 17:20

8

Sirius101, идея есть, но я не хочу её озвучивать. Будет лучше если ты самостоятельно разберешься.



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

21.07.2015, 17:20

Помогаю со студенческими работами здесь

Как можно отнять от текущей даты 30 дней 60 дней и т.д
Есть функция

mktime(0, 0, 0, date(‘d’) – 30, date(‘m’), date(‘y’))

так не работает, как можно…

Реализовать класс “Счётчик” (Найти и исправить ошибки в коде)
Вот условие:

"Цифровой счетчик, это переменная с ограниченным
диапазоном. Значение которой…

Вывести число дней в заданном году, учитывая, что обычный год насчитывает 365 дней, а високосный — 366 дней
11 Дан номер некоторого года (положительное целое число). Вывести число дней в этом году, учитывая,…

Вывести число дней в этом году, учитывая, что обычный год насчитывает 365 дней, а високосный — 366 дней
Дан номер некоторого года (положительное целое число). Вывести число дней в этом году, учитывая,…

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

8

Содержание

  • System.Diagnostics
  • Простой пример использования Stopwatch
  • Stopwatch
    • Свойства Stopwatch
      • Elapsed
      • ElapsedMilliseconds
      • ElapsedTicks
      • IsRunning
    • Поля Stopwatch
      • Frequency
      • IsHighResolution
    • Методы Stopwatch
      • Start и Stop
      • StartNew
      • Reset
      • Restart
    • Итого

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

При разработке различных программ иногда бывает необходимо измерить точное время какой-либо операции, например, узнать сколько времени требуется на загрузку данных из файла, запись в базу данных и так далее. Сегодня мы рассмотрим то, как измерить время выполнения операции в C#, используя стандартные средства и возможности языка.

System.Diagnostics

Пространство имен System.Diagnostics содержит классы, позволяющие нашим приложениям взаимодействовать с журналами событий, системными процессами и счётчиками производительности. В числе прочего, это пространство имен содержит класс под названием Stopwatch, который можно в своих приложениях C# использовать для точного измерения затраченного времени. Именно об этом классе мы сегодня и поговорим.

Простой пример использования Stopwatch

Для начала, рассмотрим простой пример использования класса Stopwatch для измерения затраченного времени на выполнение операции.

namespace StopwatchExample
{
    class Program
    {
        static void Main(string[] args)
        {
            //создаем объект
            Stopwatch stopwatch = new Stopwatch();
            //засекаем время начала операции
            stopwatch.Start();
            //выполняем какую-либо операцию
            for (int i = 0; i < 10001; i++)
            {
                Console.WriteLine(i);
            }
            //останавливаем счётчик
            stopwatch.Stop();
            //смотрим сколько миллисекунд было затрачено на выполнение
            Console.WriteLine(stopwatch.ElapsedMilliseconds);
        }
    }
}

Чтобы измерить время выполнения операции в C# нам необходимо выполнить несколько простых шагов:

  1. Создать объект класса Stopwatch;
  2. Выполнить метод Start() для того, чтобы засечь время начала операции;
  3. Выполнить метод Stop() для того, чтобы засечь время окончания операции;
  4. Воспользоваться одним из свойств объекта для получения данных о затраченном на выполнение операции времени.

В примере использовано свойство ElapsedMilliseconds, которое позволяет получить количество миллисекунд, затраченных на выполнение операции. Рассмотрим какие ещё есть свойства и методы у класса Stopwatch.

Stopwatch

Свойства Stopwatch

Elapsed

Свойство Elapsed позволяет получить общее затраченное время, измеренное текущим экземпляром класса Stopwatch. Описание свойства выглядит следующим образом:

public TimeSpan Elapsed { get; }

Свойство возвращает объект типа TimeSpan — интервал времени, используя который, можно получить время выполнения операции в удобном для вас виде. Например,

//получаем объект TimeSpan
TimeSpan ts = stopwatch.Elapsed;
// Создаем строку, содержащую время выполнения операции.
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
    ts.Hours, ts.Minutes, ts.Seconds,
    ts.Milliseconds / 10);
Console.WriteLine(elapsedTime);

ElapsedMilliseconds

Свойство ElapsedMilliseconds позволяет получить общее затраченное время, измеренное текущим экземпляром класса Stopwatchв миллисекундах. В примере использования класса Stopwatch выше продемонстрировано использование этого свойства.

ElapsedTicks

Свойство ElapsedTicks позволяет получить общее время выполнение операции в тактах таймера, измеренное текущим экземпляром Stopwatch. Такт — это наименьшая единица времени, которую Stopwatch может измерять таймер. В следующем примере показано использование свойства ElapsedTicks для измерения времени, затраченного на преобразование строки в целое число типа int.

int num;
//создаем объект
Stopwatch stopwatch = new Stopwatch();
//засекаем время начала операции
stopwatch.Start();

num = int.Parse("135");

//останавливаем счётчик
stopwatch.Stop();
Console.WriteLine($"num = {num}");
//смотрим сколько тактов было затрачено на выполнение
Console.WriteLine(stopwatch.ElapsedTicks);

Результатом выполнения этого кода может быть вот такой вывод консоли:

IsRunning

Свойство IsRunning позволяет получить значение типа bool, указывающее на то запущен ли в данный момент таймер Stopwatch.

Поля Stopwatch

Класс Stopwatch содержит два статических поля, позволяющих получить сведения о настройках таймера.

Frequency

Поле Frequency содержит частоту таймера в виде количества тактов в секунду.

public static readonly long Frequency;

Это поле удобно использовать вместе со свойством ElapsedTicks для преобразования количества тактов в секунды. Например,

int num;
long freq = Stopwatch.Frequency; //частота таймера
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
num = int.Parse("135");
//останавливаем счётчик
stopwatch.Stop();
double sec = (double)stopwatch.ElapsedTicks / freq; //переводим такты в секунды
Console.WriteLine($"num = {num} rn Частота таймера {freq} такт/с rn Время в тактах {stopwatch.ElapsedTicks} rn Время в секундах {sec}");

Обращу внимание только на то, как происходит перевод тактов в секунды. Учитывая особенности деления целых чисел в C#, для того, чтобы получить конкретное значение секунд нам потребовалось привести одно из значений (в данном случае значение свойства ElapsedTicks) к типу double.

IsHighResolution

Свойство IsHighResolution указывает, зависит ли таймер Stopwatch от счетчика производительности высокого разрешения (true) или же использует класс DateTime (false).

public static readonly bool IsHighResolution;

Пример использования поля

class Program
{
    static void Main(string[] args)
    {
        DisplayTimerProperties();
    }

    public static void DisplayTimerProperties()
    {
        if (Stopwatch.IsHighResolution)
        {
            Console.WriteLine("Операции рассчитываются с использованием системного счетчика производительности с высоким разрешением.");
        }
        else
        {
            Console.WriteLine("Операции рассчитываются с использованием класса DateTime.");
        }

        long frequency = Stopwatch.Frequency;
        Console.WriteLine($"  Частота таймера = {frequency}");
        long nanosecPerTick = (1000L * 1000L * 1000L) / frequency;
        Console.WriteLine($"  Таймер работает с точностью до {nanosecPerTick} наносекунд");
    }
}

Вывод консоли будет иметь следующий вид:

Операции рассчитываются с использованием системного счетчика производительности с высоким разрешением.

Частота таймера = 10000000

Таймер работает с точностью до 100 наносекунд

Методы Stopwatch

Рассмотрим основные методы класса Stopwatch, которые мы можем использовать для измерения точного времени выполнения операции в C#.

Start и Stop

Метод Start() запускает или возобновляет работу таймера Stopwatch. В свою очередь, Stop() выполняет противоположную операцию — останавливает работу таймера. Использование этих методов продемонстрировано в самом первом примере из этой статьи.

StartNew

Метод StartNew() выполняет сразу несколько операций — он инициализирует новый экземпляр класса Stopwatch, обнуляет счётчик затраченного времени и запускает таймер. То есть, этот метод позволяет немного сократить исходный код программы. Например, код из первого примера можно было бы записать вот так:

Stopwatch stopwatch = Stopwatch.StartNew();//создаем и запускаем таймер
for (int i = 0; i < 10001; i++) 
{ 
    Console.WriteLine(i);
}
//останавливаем счётчик 
stopwatch.Stop(); //смотрим сколько миллисекунд было затрачено на выполнение 
Console.WriteLine(stopwatch.ElapsedMilliseconds);

Reset

Метод Reset() останавливает измерение интервала времени и обнуляет счётчик затраченного времени. Использование Reset() позволяет избежать создания новых экземпляров Stopwatch для измерения времени, затраченного на выполнение нескольких операций в C#.

Stopwatch stopwatch = Stopwatch.StartNew();//создаем и запускаем таймер
for (int i = 0; i < 100; i++) 
{ 
    Console.WriteLine(i);
}
//останавливаем счётчик 
stopwatch.Stop(); //смотрим сколько миллисекунд было затрачено на выполнение 
Console.WriteLine($"Первая операция {stopwatch.ElapsedMilliseconds}");

stopwatch.Reset(); //сбросили счётчик
stopwatch.Start(); //запустили счётчик
for (int i = 0; i < 100; i++)
{
    Console.WriteLine(i*i);
}
stopwatch.Stop(); //смотрим сколько миллисекунд было затрачено на выполнение 
Console.WriteLine($"Вторая операция {stopwatch.ElapsedMilliseconds}");

Restart

Метод Restart() останавливает измерение интервала времени, обнуляет затраченное время и повторно запускает таймер. Таким образом, предыдущий пример можно переписать следующим образом:

Stopwatch stopwatch = Stopwatch.StartNew();//создаем и запускаем таймер
for (int i = 0; i < 100; i++) 
{ 
    Console.WriteLine(i);
}
//останавливаем счётчик 
stopwatch.Stop(); //смотрим сколько миллисекунд было затрачено на выполнение 
Console.WriteLine($"Первая операция {stopwatch.ElapsedMilliseconds}");

stopwatch.Restart(); //перезапускаем счётчик

for (int i = 0; i < 100; i++)
{
    Console.WriteLine(i*i);
}
stopwatch.Stop(); //смотрим сколько миллисекунд было затрачено на выполнение 
Console.WriteLine($"Вторая операция {stopwatch.ElapsedMilliseconds}");

Итого

Класс Stopwatch из пространства имен System.Diagnostics C# позволяет измерить время выполнения операции с точностью до 100 наносекунд в зависимости от того, что используется для работы с интервалами времени — таймер высокого разрешения или же класс DateTime.

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Время на прочтение
8 мин

Количество просмотров 19K

Введение

Добрый день!

В своем первом посте я хотел бы поделитьcя опытом использования такой утилиты как logman, с помощью которой можно собирать информацию о потреблении ресурсов (и не только) приложением под Windows.

В один из дней на работе была поставлена задача снятия метрик производительности для одного приложения под Windows. Главным условием было использовать по минимуму какие-либо сторонние утилиты, и так как опыта в подобных вещах у меня к тому времени не было, немного покопавшись, выбор пал на logman. Особой точности не требовалось и надо было лишь понять характер потребления ресурсов приложением, для чего logman с первого взгляда вполне подходил.

Итак, перейдем непосредственно к сути поста.

Что же такое logman?

Многие из вас скорее всего в работе или для домашних нужд использовали нативную Windows утилиту Performance monitor (perfmon). Так вот logman — это грубо говоря command line представление perfmon’а. Он позволяет создавать, запускать, останавливать счетчики производителности, писать результат во внешние файлы и много чего еще. Мне был необходим только базовый функционал, который я и опишу ниже.

Основные операции

Небольшое замечание: для выполнения нижеследующих операций необходимо обладать правами администратора, иначе может вылететь такая ошибка.

Ошибка:
Отказано в доступе.
Используется ограниченный токен, используйте расширенный.

Просмотр созданных и запущенных счетчиков

Посмотреть список сборщиков данных можно командой logman
В результате чего будет получен примерно такой вывод:

Группа сборщиков данных                  Тип                           Состояние
-------------------------------------------------------------------------------
cpu                                     Счетчик                       Остановлено

Команда выполнена успешно.

Создание счетчика производительности

Для создания счетчика я использовал следующую команду (с полным списком опций можно ознакомиться в официальной документации.):

logman create counter "counter_name" -f csv -si "interval" --v -o "output_file" -c counter
  • counter_name — имя счетчика. Может быть любым, например «explorer_cpu»
  • -f — формат файла с результатами измерений
  • –v — эта опция подавляет вывод версии в выходном файле
  • -si — интервал. с которым будут записываться измерения
  • -o — файл с результатами измерений
  • -c — идентификатор счетчика производительности

Остановимся подробнее на последней опции. Чтобы понять, что вписывать в поле «counter», можно проследовать в perfmon, создать группу сборщиков данных и выбрать «Создать -> Сборщик данных». Далее выбрать «Добавить счетчик» и в появившемся окне найти интересующий нас тип счетчика.

Меня интересовало потребление cpu и памяти конкретным процессом, поэтому я использовал для измерений следующие счетчики (в расчете CPU мне помог следующий пост):

  • “Processor(_Total)% User time” — процент CPU в пользовательском режиме
  • “Process(application_name)% Processor time” — доля CPU приложения от пользовательского режима
  • “Process(application_name)Working Set” — использование оперативной памяти процессом

Процент потребления CPU процессом можно расчитать как (“Processor(_Total)% User time” * “Process(application_name)% Processor time”) / (количество_процессоров * 100)

Счетчики можно записывать через пробел, тогда в выходном файле значения будут каждый в своем столбце.

В итоге приведу пример готовой команды для создания счетчика:

logman create counter "explorer-cpu.usage" -f csv -si 1 --v -o "d:logman-testrawexplorer-cpu.usage.csv" -c "Processor(_Total)% User time" "Process(explorer)% Processor time"

Запуск и остановка счетчика

Выполняются соответствующими командами:

logman start "counter_name"

logman stop "counter_name"

Удаление счетчика

Удалить счетчик можно следующей командой (он обязательно должен быть перед этим остановлен):

logman delete "counter_name"

Обертка на Python

Прежде чем перейти к коду, хотелось бы рассказать о небольшой (хотя для меня она стала довольно существенной) проблеме, которая возникла в ходе сбора метрик.

Так как собирать данные предполагалось за довольно небольшой промежуток времени (5-15 секунд), то стало понятно, что интервал сбора в 1 с (задаваемый через опцию “-si”) слишком большой. Поискав на просторах интернета и в оф. документации, мне не удалось найти способ, которым этот интервал можно было уменьшить, а количество получаемых точек на графике очень хотелось увеличить. Немного поразмыслив, я решил пойти от противного — если нельзя уменьшить интервал, то можно увеличить количетство счетчиков. Таким образом, запуская подряд несколько сборщиков с интервалом в 100-500 миллисекунд, можно получить за одну секунду сколько нужно данных.

Процесс сбора данных должен был быть интегрирован в существующий автоматический тест и в конечном была написана небольшая вспомогательная обертка для выполения всех вышеуказанных действий.

Ниже представлен исходный код модуля, собирающий данные по CPU и оперативной памяти для указанного приложения с требуемой точностью.

pylogman.py

import os
import logging
import random
import time
import subprocess
import glob
import multiprocessing


CPU_USER_COUNTER = '"Processor(_Total)% User time"'
CPU_APP_COUNTER = '"Process({app})% Processor time"'
MEMORY_COUNTER = '"Process({app})Working Set"'
APP_PLACEHOLDER = '{app}'


class PerflogManager(object):

    def __init__(self, app_name, precision, results_dir, max_mem=1, interval=1):
        """
        Args:
            app_name: name of the application without "exe" extention
            precision: amount of
            results_dir: output folder
            max_mem: this value is used to calculate % from total avaliable memory for further plotting
            interval: interval which will be used as "-si" logman option value
        """

        self._app_name = app_name
        self._precision = precision
        self._counters = { 'cpu.usage': '{cpu_user} {cpu_app}'.format(cpu_user=CPU_USER_COUNTER,
                                                                      cpu_app=CPU_APP_COUNTER).replace(APP_PLACEHOLDER, app_name),
                           'mem.usage': MEMORY_COUNTER.replace(APP_PLACEHOLDER, app_name) }
        self._results_dir = os.path.normpath(results_dir)
        self._raw_dir = os.path.join(self._results_dir, 'raw')
        self._final_dir = os.path.join(self._results_dir, 'csv')
        self._interval = interval
        self._max_mem = max_mem
        self._collectors = []
        if not os.path.exists(self._results_dir):
            os.makedirs(self._results_dir)
            os.makedirs(self._raw_dir)
            os.makedirs(self._final_dir)
            logging.info('Directory "{path}" for logman results has been created.'.format(path=self._results_dir))
        logging.info('Performance logman manager has been created for "{}" application.'.format(self._app_name))


    def init_collectors(self):
        """
        Creates collectors by "logman create" command
        """

        logging.info('Creating collectors set...')
        for lang in self._counters:
            for idx in range(self._precision):
                collector = '{app}-{collector}-{id}'.format(app=self._app_name,
                                                            collector=lang,
                                                            id=idx)
                output = os.path.join(self._raw_dir, collector + '.csv')
                self.__create(collector, self._counters[lang], output)
                self._collectors.append(collector)


    def start_all(self):
        """
        Starts all the collectors from self._collectors list
        """

        for collector in self._collectors:
            self.__start(collector)
            time.sleep(random.uniform(0.1, 0.9))


    def stop_all(self):
        """
        Stops and deletes all initiated collectors from self._collectors list
        """

        for collector in self._collectors:
            self.__stop(collector)
            self.__delete(collector)


    def cleanup(self):
        """
        Cleans raw_dir directory which contains unprocessed csv file from logman
        """
        logging.info('Cleaning results directory from unnecessary files.')
        for collector in self._collectors:
            csv = os.path.join(self._raw_dir, '{}.csv'.format(collector))
            if os.path.isfile(csv):
                os.remove(csv)


    def process_csv(self):
        """
        Composes and formats data from all counters for further plotting
        """

        for lang in self._counters:
            final_output = os.path.join(self._final_dir, '{}.csv'.format(lang))
            self.__compose_csv(final_output, lang)
            self.__format_data(final_output)


    def __compose_csv(self, output, counter):
        """
        Concatenates gathered csv data to one file
        """

        logging.info('Composing file "{}".'.format(output))
        try:
            with open(output, 'a') as outfile:
                for csv in glob.glob(os.path.join(self._raw_dir, '*{}*'.format(counter))):
                     with open(csv, 'r') as file:
                        outfile.writelines(file.readlines()[1:]) # Get rid of a file header with service info
            logging.info('File {} successfully created.'.format(output))
        except (FileNotFoundError, IOError) as e:
            logging.error('Failed to compose file {file}: {exception}'.format(file=output,
                                                                              exception=e))


    def __format_data(self, file):
        """
        Sorts data after self.__compose_csv function and calculates % of CPU and Memory
        """

        try:
            with open(file, 'r') as csv:
                raw_data = csv.readlines()
            with open(file, 'w') as csv:
                sorted_data = [line.replace('"', '').replace(',', ';')
                            for line in sorted(raw_data)
                            if '" "' not in line]
                csv_data = []
                if 'cpu' in file:
                    for line in sorted_data:
                        time, cpu_user, cpu_app = line.split(';')
                        cpu = (float(cpu_user) * float(cpu_app)) / (multiprocessing.cpu_count() * 100)
                        csv_data.append('{};{:.2f}n'.format(time, cpu))
                if 'mem' in file:
                    for line in sorted_data:
                        time, total_memory = line.split(';')
                        mem = float(total_memory) / (self._max_mem * 10000)
                        csv_data.append('{};{:.2f}n'.format(time, mem))
                csv.writelines(csv_data)
        except (FileNotFoundError, IOError) as e:
            logging.error('Failed to process file "{file}": {exception}'.format(file=file,
                                                                                exception=e))


    def __logman(self, cmd):
        """
        Default wrapper for logman commands

        Args:
            cmd: windows command to be executed
        """

        try:
            logging.debug('Running {}'.format(cmd))
            subprocess.check_call(cmd)
        except (subprocess.CalledProcessError, OSError) as e:
            logging.error('Failed to execute command "{}": {}.'.format(cmd, e))


    def __create(self, name, counter, output):
        """
        Creates logman counter

        Args:
            name: uniq name of a collector
            counter: type of the counter (can be taken from perfmon)
            output: csv file for results
        """

        logging.info('Creating collector "{}"'.format(name))
        cmd = 'logman create counter "{name}" -f csv -si {interval} ' 
              '--v -o "{output}" -c {counter}'.format(name=name,
                                                      interval=str(self._interval),
                                                      output=output,
                                                      counter=counter)
        self.__logman(cmd)


    def __start(self, name):
        """
        Starts logman collector

        Args:
            name: uniq name of a collector
        """

        logging.info('Starting collector "{}".'.format(name))
        cmd = 'logman start {}'.format(name)
        self.__logman(cmd)


    def __stop(self, name):
        """
        Stops logman collector

        Args:
            name: uniq name of a collector
        """

        logging.info('Stopping collector "{}".'.format(name))
        cmd = 'logman stop {}'.format(name)
        self.__logman(cmd)


    def __delete(self, name):
        """
        Deletes logman collector

        Args:
            name: uniq name of a collector
        """

        logging.info('Deleting collector "{}".'.format(name))
        cmd = 'logman delete {}'.format(name)
        self.__logman(cmd)


if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    app = 'skype'
    start_time = time.strftime('%Y%m%d-%H%M%S', time.gmtime())
    logman = PerflogManager(app, 3, 'd:/logman-test/')
    logman.init_collectors()
    logman.start_all()
    time.sleep(20)
    logman.stop_all()
    logman.process_csv()

Заключение

В заключении хотелось бы сказать, что logman — довольно полезная утилита, если небходимо с минимальными затратами автоматизировать сбор метрик производительности под Windows. В сжатые сроки мне не удалось найти более удобного способа, так что буду рад узнать о других путях и подходах в решении такого рода задач в комментариях.

У многих начинающих программистов рано или поздно возникает вопрос: «Как найти время работы программы?». В интернете много ответов на данный вопрос: написать свой мини-дебаггер, посчитать количество тактов и т. д. Самый простой вариант — это посчитать разницу между начальным временем и конечным. То есть, есть начальное значение времени, после которого объявлен фрагмент кода, время выполнения которого необходимо измерить. После фрагмента кода фиксируется ещё одно, конечное, значение времени. После чего, из конечного значения времени вычитаем начальное время и получим время, за которое выполнился измеряемый фрагмент кода или вся программа. Время работы программы  необходимо найти для того, чтобы проверить, насколько эффективнее стал работать отдельный алгоритм или программа в целом! Как это сделать,смотрите ниже.

// Как найти время работы фрагмента кода?

// заголовочный файл с прототипом функции clock()
#include <ctime> 
//         ...
    unsigned int start_time =  clock(); // начальное время
    // здесь должен быть фрагмент кода, время выполнения которого нужно измерить
    unsigned int end_time = clock(); // конечное время
    unsigned int search_time = end_time - start_time; // искомое время

Для того, чтобы найти время работы программы, нужно воспользоваться функцией clock(). Прототип функции clock() находится в заголовочном файле <ctime>, который нужно подключить, строка 4. Функция clock() возвращает значение времени в миллисекундах (1с = 1000млс). Причём  отсчёт времени начинается с момента запуска программы. Если надо измерить работу всей программы, то в конце программы, перед оператором return 0;  нужно запустить функцию clock(), которая покажет рабочее время. Для поиска времени работы фрагмента кода нужно найти разницу между конечным и начальным временем, как показано выше.

// Как найти время работы программы?

    // заголовочный файл с прототипом функции clock()
    #include <ctime> 
    //         ...
    // здесь должен быть код программы, время выполнения которой нужно измерить
    unsigned int end_time = clock(); // время работы программы

Разработаем программу, в которой с помощью функции clock() вычислим время работы программы. Программа ищет минимальное значение в массиве размером в 200000 элементов. Размер массива специально выбран большим, для того, чтобы было заметно, как работает программа. Так как числа генерируются случайно, то при каждом запуске получается новый случай, и время может не совпадать. К тому же, время выполнения программы зависит от того, насколько загружен компьютер и от того, какая у компьютера вычислительная мощность. На разных машинах по-разному  будет затрачиваться время на выполнение программы, на более мощных компьютерах затрачиваемое время будет меньше и наоборот.

  • MVS
  • Code::Blocks
  • Dev-C++
  • QtCreator
// runtime.cpp: определяет точку входа для консольного приложения.
// Как найти время работы программы?

#include "stdafx.h"
#include <iostream>
#include <ctime>                     
using namespace std;

int main(int argc, char* argv[])
{
    srand(time(0));
    const int array_size = 200000; // размер одномерного массива
    int array1[array_size]; // объявление одномерного массива
    for (int counter = 0; counter < array_size; counter++)
    {
     array1[counter] = rand() % 50 - rand() % 50; // заполняем массив случайными значениями в диапазоне от -49 до 49 включительно
     cout << array1[counter] << " "; // печать элементов одномерного массива array1
    }
    int min = array1[0]; // переменная для хранения минимального значения
    for (int counter = 1; counter < array_size; counter++)
    {
     if ( min > array1[counter] ) // поиск минимального значения в одномерном массиве
         min = array1[counter];
    }
    cout << "nmin = " << min << endl; 
    cout << "runtime = " << clock()/1000.0 << endl; // время работы программы                   
    system("pause");
    return 0;
}
// runtime.cpp: определяет точку входа для консольного приложения.
// Как найти время работы программы?

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;

int main(int argc, char* argv[])
{
    srand(time(0));
    const int array_size = 200000; // размер одномерного массива
    int array1[array_size]; // объявление одномерного массива
    for (int counter = 0; counter < array_size; counter++)
    {
     array1[counter] = rand() % 50 - rand() % 50; // заполняем массив случайными значениями в диапазоне от -49 до 49 включительно
     cout << array1[counter] << " "; // печать элементов одномерного массива array1
    }
    int min = array1[0]; // переменная для хранения минимального значения
    for (int counter = 1; counter < array_size; counter++)
    {
     if ( min > array1[counter] ) // поиск минимального значения в одномерном массиве
         min = array1[counter];
    }
    cout << "nmin = " << min << endl;
    cout << "runtime = " << clock()/1000.0 << endl; // время работы программы
    return 0;
}

В строке 26 запускается функция clock(), которая скажет сколько потребовалось время программе. Разбирать алгоритм поиска не нужно, так как это совсем другая тема. Главное, нужно понять, как использовать функцию clock(), для поиска времени работы программы или отдельного фрагмента кода. А именно, в строке 26, после основного кода программы, но до оператора return 0; объявлена функция clock(), которая вернёт значение времени. Результат работы программы (см. Рисунок 1).

CppStudio.com

-13 4 -2 30 8 9 27 10 11 -14 -31 1 6 -16 38 31 38 -26 22 21 13 16 42 11 2 11 25
12 0 3 -7 -38 -8 -4 0 42 29 -27 -8 6 -24 12 -12 -5 27 -21 11 5 -28 33 -6 -27 19
8 -24 -4 20 -33 16 13 30 38 -3 25 -8 30 13 -19 -7 -19 12 11 -11 -14 -33 12 -5 -2
7 10 16 -14 -23 10 -10 4 -19 15 27 20 23 -5 34 12 19 -19 -13 30 -11 6 -7 -16 27
-11 -19 -9 26 -3 0 -7 41 -3 -31 10 2 -4 5 15 -37 6 -10 -10 25 -28 7 17 19 -38 15
 12 -27 -48 6 36 -35 18 -17 -20 28 -13 -32 -27 7 38 16 1 25 -16 -10 5 -26 31 -15
 8 22 13 6 -5 11 -31 -3 -31 10 8 -3 19 -43 8 -29 -21 -8 3 44 32 -5 9 -23 19 -6 3
6 -7 -9 23 -31 2 -19 -2 -3 -5 -5 36 12 -14 21 5 9 10 13 21 -21 12 12 14 18 -27 -
26 -6 -6 -46 7 12 -16 -24 -26 18 -1 9 2 15 -12 17 20 19 -6 0 -1 -16 11 26 -12 0
-28 12 -26 -2 23 -1 0 11 -13 -34 6 22 4 -35 37 15 -15 -26 31 25 -4 2 19 0 7 -21
26 -1 -13 37 28 -13 4 22 22 5 34 2 8 6 -15 -1 25 25 0 22 -17 3 -27 1 43 8 41 -25
 12 -15 32 -14 -6 -2 24 22 -33 0 -31 32 17 -32 -22 22 -32 0 3 -24 7 2 40 -28 -39
 24 -5 12 -1 -1 27
min = -49
runtime = 59.449
Для продолжения нажмите любую клавишу . . .

Рисунок 1 — Как найти время работы программы

На рисунке 1 видно, что время выполнения программы приблизительно равно 59 секунд. Даже если элементы массива неизменны, время всё равно будет немного отличаться при повторном запуске программы, так как некоторые ресурсы компьютера постоянно будут заняты, а значит, не доступны программе. Если Вы запустите эту программу у себя на компьютере, то время выполнения программы может быть совсем другим, так как наши машины не идентичны.

Добавить комментарий