Выполнение измерений характеристик кода в среде visual studio практическая работа
Эти правила по умолчанию отключены, но их можно включить в Обозреватель решений или в файле EditorConfig . Например, чтобы включить правило CA1502 в виде предупреждения, файл EditorConfig будет содержать следующую запись:
Конфигурация
Вы можете настроить пороговые значения, при которых будут срабатывать правила метрики кода.
Создание текстового файла. Например, можно присвоить имя CodeMetricsConfig.txt.
Добавьте необходимые пороговые значения в текстовый файл в следующем формате:
В этом примере правило CA1502 настраивается на срабатывание, когда сложность сложностью организации циклов метода больше 10.
в окне свойства Visual Studio или в файле проекта пометьте действие сборки файла конфигурации как аддитионалфилес. Пример:
Команда меню «вычислить метрики кода»
Создайте метрики кода для одного или всех открытых проектов в интегрированной среде разработки с помощью меню анализ > метрик кода .
Создание результатов метрик кода для всего решения
Вы можете создавать Результаты метрик кода для всего решения одним из следующих способов:
В строке меню выберите анализ > рассчитать метрики кода > для решения.
В Обозреватель решений щелкните правой кнопкой мыши решение и выберите пункт рассчитать метрики кода.
В окне Результаты метрик кода выберите кнопку вычислить метрики кода для решения .
Результаты будут сформированы, и откроется окно результаты метрики кода . Чтобы просмотреть подробные сведения о результатах, разверните дерево в столбце Иерархия .
Создание результатов метрик кода для одного или нескольких проектов
В Обозреватель решений выберите один или несколько проектов.
в строке меню выберите анализ > рассчитать метрики кода > для выбранных Project.
Результаты будут сформированы, и откроется окно результаты метрики кода . Чтобы просмотреть подробные сведения о результатах, разверните дерево в иерархии.
Вместо этого вычислить метрики кода из командной строки
Метрики кода командной строки
пакет Microsoft. CodeAnalysis. metrics NuGet
самый простой способ создать данные метрик кода из командной строки — установить пакет Microsoft. CodeAnalysis. метрики NuGet. После установки пакета запустите msbuild /t:Metrics из каталога, содержащего файл проекта. Пример:
Можно переопределить имя выходного файла, указав /p:MetricsOutputFile= . Вы также можете получить данные метрик кода в стиле прежних версий , указав /p:LEGACY_CODE_METRICS_MODE=true . Пример:
Выходные данные метрик кода
Созданный выход XML имеет следующий формат:
Metrics.exe
если вы не хотите устанавливать пакет NuGet, можно создать и использовать Metrics.exe исполняемый файл напрямую. Чтобы создать Metrics.exe исполняемый файл:
откройте Командная строка разработчика для Visual Studio с правами администратора.
В корне репозитория Roslyn-Analyzers выполните следующую команду: Restore.cmd
Измените каталог на срк\тулс\метрикс.
Выполните следующую команду, чтобы выполнить сборку проекта метрик. csproj :
Исполняемый файл с именем Metrics.exe создается в каталоге артифактс\бин в корне репозитория.
Использование Metrics.exe
Чтобы запустить Metrics.exe, укажите проект или решение и выходной XML-файл в качестве аргументов. Пример:
Устаревший режим
Можно выбрать сборку Metrics.exe в устаревшем режиме. Версия средства в устаревшем режиме создает значения метрик, которые ближе к более старым версиям созданного средства. Кроме того, в устаревшем режиме Metrics.exe создает метрики кода для того же набора типов методов, для которого в предыдущих версиях средства сформированы метрики кода. Например, он не создает данные метрик кода для инициализаторов полей и свойств. Устаревший режим удобен для обеспечения обратной совместимости или при наличии шлюзов возврата кода на основе номеров метрик кода. Команда для сборки Metrics.exe в устаревшем режиме:
предыдущих версий
Visual Studio 2015 включает средство метрик кода командной строки, которое также называется Metrics.exe. Предыдущая версия средства выполняла двоичный анализ, то есть анализ на основе сборок. Более новая версия средства Metrics.exe анализирует исходный код. поскольку более новая Metrics.exe средство является исходным кодом, результаты метрик кода командной строки могут отличаться от результатов, создаваемых интегрированной средой разработки Visual Studio, и предыдущими версиями Metrics.exe. начиная с Visual Studio 2019, интегрированная среда разработки Visual Studio анализирует исходный код, подобный средству командной строки, и результаты должны быть одинаковыми.
Visual Studio 2015 включает средство метрик кода командной строки, которое также называется Metrics.exe. Предыдущая версия средства выполняла двоичный анализ, то есть анализ на основе сборок. Новое средство Metrics.exe анализирует исходный код. поскольку новый инструмент Metrics.exe основан на исходном коде, результаты метрик кода командной строки отличаются от результатов, создаваемых интегрированной средой разработки Visual Studio и предыдущими версиями Metrics.exe.
Новое средство метрик кода командной строки выдает метрики даже при наличии ошибок исходного кода, пока решение и проект могут быть загружены.
Различия в значениях метрик
начиная с Visual Studio 2019 версии 16,4 и Microsoft. CodeAnalysis. метрики (2.9.5), SourceLines ExecutableLines замените предыдущую LinesOfCode метрику. Описание новых метрик см. в разделе значения метрик кода. LinesOfCode Метрика доступна в устаревшем режиме.
Эта LinesOfCode Метрика более точная и надежная в новом инструменте для метрик кода командной строки. Он не зависит от CodeGen различий и не изменяется при изменении набора инструментов или среды выполнения. Новое средство подсчитывает фактические строки кода, включая пустые строки и комментарии.
Другие метрики, такие как CyclomaticComplexity и, MaintainabilityIndex используют те же формулы, что и предыдущие версии Metrics.exe, но новое средство подсчитывает количество IOperations (инструкции логического источника) вместо инструкций промежуточного языка (IL). числа будут немного отличаться от тех, которые создаются Visual Studio IDE и предыдущими версиями Metrics.exe.
Повышенная сложность современных программных приложений также повышает сложность обеспечения надежности и сопровождения кода. Метрики кода представляют собой набор оценок программного обеспечения, которые дают разработчикам более глубокое представление о разрабатываемом коде. Используя преимущества метрик кода, разработчики могут понять, какие типы и методы должны быть переработаны или тщательно протестированы. Группы разработчиков могут выявление потенциальных рисков, понимание текущего состояния проекта и отслеживание хода выполнения во время разработки программного обеспечения.
разработчики могут использовать Visual Studio для создания данных метрик кода, которые измеряют сложность и удобство обслуживания управляемого кода. Данные метрик кода могут создаваться для всего решения или отдельного проекта.
сведения о создании данных метрик кода в Visual Studio см. в разделе инструкции. создание данных метрик кода.
Программные измерения
в следующем списке показаны результаты метрик кода, которые Visual Studio вычисляют:
Индекс удобства обслуживания — вычисляет значение индекса от 0 до 100, представляющее относительную простоту обслуживания кода. Высокое значение означает лучшую сопровождаемость. Для быстрого обнаружения проблем в коде можно использовать цветовую маркировку. Зеленая Оценка находится в диапазоне от 20 до 100 и указывает на то, что код обладает хорошей сопровождаемостью. Желтая Оценка находится в диапазоне от 10 до 19 и указывает, что код является умеренно поддерживаемым. Красная Оценка — это оценка между 0 и 9 и указывает на низкую сопровождаемость. Дополнительные сведения см. в разделе Диапазон индекса для удобства поддержки и значение.
Сложностью организации циклов сложность — измеряет структурную сложность кода. Он создается путем вычисления количества различных путей кода в потоке программы. Программа, имеющая сложный поток управления, требует больше тестов для достижения хорошего объема протестированного кода и менее сопровождаемой. Дополнительные сведения см. в записи Википедии для сложностью организации циклов сложность.
Глубина наследования — указывает количество различных классов, которые наследуют друг от друга, вплоть до базового класса. Глубина наследования аналогична взаимосвязанности классов в том, что изменение базового класса может повлиять на любые из его унаследованных классов. Чем выше это число, тем более глубокое наследование и тем выше вероятность внесения изменений в базовый класс, что приводит к критическому изменению. Для более глубокого наследования низкое значение хорошо, а высокое значение является недопустимым.
Взаимосвязь классов — измеряет связь с уникальными классами через параметры, локальные переменные, возвращаемые типы, вызовы методов, универсальные экземпляры или шаблоны шаблонов, базовые классы, реализации интерфейса, поля, определенные во внешних типах, и декорирование атрибутов. Хорошая разработка программного обеспечения определяет, что типы и методы должны иметь высокую связность и низкую связь. Высокая связь указывает на проект, который трудно использовать и поддерживать из-за множества взаимозависимостей от других типов. Дополнительные сведения см. в разделе соединение классов.
Строки исходного кода — указывает точное число строк исходного кода, имеющихся в исходном файле, включая пустые строки. эта метрика доступна начиная с Visual Studio 2019 версии 16,4 и Microsoft. CodeAnalysis. метрик (2.9.5).
Строки исполняемого кода — указывает приблизительное количество строк или операций исполняемого кода. Это количество операций в исполняемом коде. эта метрика доступна начиная с Visual Studio 2019 версии 16,4 и Microsoft. CodeAnalysis. метрик (2.9.5). Значение обычно является близким к предыдущей метрике, строкам кода, которая является метрикой на основе инструкций языка MSIL, используемой в устаревшем режиме.
Строки кода — указывает приблизительное количество строк в коде. Количество основывается на коде IL и, следовательно, не является точным числом строк в файле исходного кода. Большое число может означать, что тип или метод пытается выполнить слишком много усилий и должны быть разделены. Оно также может указывать на то, что тип или метод может быть трудно поддерживать.
Версия командной строки средства метрики кода считает фактические строки кода, поскольку анализирует исходный код, а не IL.
Анонимные методы
Анонимный метод — это просто метод без имени. Анонимные методы чаще всего используются для передачи блока кода в качестве параметра делегата. Результаты метрик кода для анонимного метода, объявленного в элементе, например метод или метод доступа, связаны с членом, который объявляет метод. Они не связаны с членом, который вызывает метод.
Созданный код
Некоторые программные средства и компиляторы создают код, который добавляется в проект, и разработчик проекта не может видеть или не должен изменять его. В основном метрики кода игнорируют сформированный код при вычислении значений метрик. Это позволяет значениям метрик отражать, что может видеть и изменять разработчик.
код, созданный для Windows Forms, не пропускается, так как это код, который разработчик может просматривать и изменять.
Метрика программного обеспечения (англ. Software metric) – это некая мера определенного свойства программного обеспечения или же его спецификаций. Как известно, мера – это средство измерения. Важно понять, что мера - это числовое значение. Таким образом, метрика программного обеспечения будет показывать некое числовое значение определенного свойства ПО.
Мы не будем углубляться в теорию, так как ее можно найти в свободном доступе довольно легко. Мы займемся практической частью данного вопроса. А именно: как нам использовать метрики для улучшения кода?
Метрики в Visual Studio
Стоит заметить сразу, что метрики подвергаются критике. Это, как минимум, поверхностно и неточно. Мы вернемся к этому после того, как поймем о чем речь. Рассматривать мы будет все на примере Visual Studio 2015 RC. Сперва, откроем проект для изучения.
Далее, мы можем видеть вкладку Analyze
В этой вкладке мы видим Calculate Code Metrics for .
Это нам и нужно. Разница лишь в том, что будет анализироваться. Или же выбранные проекты в Solution Explorer, или же сразу весь Solution. После нажатия придется немного подождать. Время зависит от конфигурации Вашего компьютера. Когда анализ будет завершен, Вы увидите внизу окно
Тема связана со специальностями:
Здесь будет видна иерархия всего Solution. В моем случае это отдельная dll библиотека и проект. Когда развернем библиотеку, мы увидим следующий уровень иерархии, и так далее
Теперь давайте разберемся со столбцами дальше.
1. Maintainability Index – это комплексный показатель качества кода. Эта метрика рассчитывается по следующей формуле:
- HV – Halstead Volume, вычислительная сложность. Чем больше операторов, тем больше значение этой метрики;
- CC – Cyclomatic Complexity (Эта метрика описана ниже);
- LoC – количество строк кода (Эта метрика описана ниже).
2. Cyclomatic Complexity – показывает структурную сложность кода. Иными словами, количество различных ветвей кода. Считается на основе операторов в Вашем коде, строя графы переходов от одного оператора к другому. К примеру, оператор if-else увеличит эту метрику, потому что здесь будут разные ветви выполнения.
3. Depth of Inheritance – глубина наследования. Для каждого класса эта метрика показывает, насколько глубоко он в цепочке наследования.
4. Class Coupling – указывает на зависимость классов друг от друга. Проект с множеством зависимостей очень трудно и дорого поддерживать.
5. Lines of Code – количество строк кода. Напрямую используется редко. В наши дни, с множеством разнообразных как подходов к программированию, так и языков, эта метрика дает нам мало полезной информации. Если брать во внимание отдельный метод, то можно разбить его на несколько методов поменьше.
Видео курсы по схожей тематике:
Синхронизация данных двух информационных систем с использованием LINQ и Entity FW 6
Использования метрик
Изначально стоит обращать внимание на Maintainability Index. Старайтесь придерживать его около 70-90. Это значительно облегчит сопровождения кода как Вами, так и другими программистами. Иногда стоит оставить его на уровне 50-60, так как переписать некоторые участки кода бывает очень затратным. Оценивайте здраво как код, так и Ваши возможности с затратами.
Стоит также уделить много внимания Class Coupling. Эта метрика должна быть как можно меньшей. Ведь она так же способствует поддержке кода. Для оптимизации возможно придется пересматривать дизайн проекта и некоторые архитектурные решения.
Теперь стоит уделить внимание Cyclomatic Complexity. Эта метрика показывает сложность кода, а это так же влияет на поддержку кода в будущем. Иногда приходится переписывать куски кода, которые писали до Вас другие люди, так как Вы просто не можете понять, что, как и зачем в этом методе. Конечно, этому еще способствует стиль кода и идея, но не забывайте о Cyclomatic Complexity при рефакторинге.
Критика
А теперь вернемся к критике. Вы, наверняка, заметили, что мы использовали на практике не все метрики, но они могут быть частью остальных, как в случае с Maintainability Index. Но стоит понимать, что оценивать качество работы программиста, исходя из метрик, нельзя. Это очень неточно и поверхностно. Иногда просто нет другого способа решения задачи, а иногда это бывает затратным. Также есть человеческий фактор, о котором не стоит забывать. Метрики бывают искаженными, ведь программист может стремится написать не эффективное и правильно решение, а оптимизировать показатели этих же метрик.
Вывод
С таким инструментом в руках Вы можете быстро и относительно легко сделать review проекта и найти его уязвимые места. Также можно постоянно мониторить метрики и делать даже некие выводы об усталости работника или его отношении к работе. Более того, можно увидеть динамику роста качества кода каждого программиста. Но здесь стоит отчетливо понимать все детали так, как мы говорили об этом в критике.
Бесплатные вебинары по схожей тематике:
Шахматная IT Арена для программистов. I тур. Доска, фигуры и ходы.
Ну и одно из самых важных, следить за недопустимыми значениями, при которых хорошо было бы провести рефакторинг кода.
Достаточно часто программистам приходится поддерживать чужой код, очень часто этот код выглядит не самым лучшим образом, и сопровождать его очень сложно. Если это приложение не придется выбросить в скором времени, то естественно его стоит привести в человеческий вид, т.е. отрефакторить. Было бы хорошо иметь какую-нибудь метрику, которая позволила бы оценить качество кода и определить места, которые стоит улучшить. Такая метрика позволила бы оценить, например, то, как программист пишет исходный код или то, насколько качественен код в том приложении, которое Вы собираетесь поддерживать.
Microsoft предоставляет встроенное в Visual Studio средство, которое позволяет оценить код вашего проекта.
Получить оценку вашего кода можно нажав правой кнопкой на проекте и выбрав пункт “Calculate Code Metrics” (Эта функциональность доступна в Visual Studio 2008 Team System и Visual Studio 2010 начиная с Premium версии).
Описание метрик
Результаты содержат 5 метрик для вашего кода.
-
Maintainability Index – комплексный показатель качества кода. Этот показатель разработан специалистами из Carnegie Mellon Software Engineering Institute. Рассчитывается метрика по следующей формуле:
MI = MAX(0, (171 — 5.2 * ln(HV) — 0.23 * CC — 16.2 * ln(LoC)) * 100 / 171)
- HV – Halstead Volume, вычислительная сложность. Чем больше операторов, тем больше значение этой метрики;
- CC – Cyclomatic Complexity. Эта метрика описана ниже;
- LoC – количество строк кода.
Реальное использование
Когда я первый раз запустил анализ на одном из проектов, все значения Maintainability Index были зеленые. Это казалось несколько странным, т.к. там явно был код, который надо было бы переписать. Значения MI для таких участков кода были около 30-40. Получается, что показатели по умолчанию являются, скорее всего, субъективными, и решение о том, какой код считать некачественным, придется принимать самим программистам.
Для своих проектов я стараюсь для большинства методов поддерживать показатель MI около 70-90. Бывают методы, у которых этот показатель равен 50-60, и их можно переписать, но стоит оценивать затраты и выгоды.
Благодаря этому инструменту можно достаточно легко провести code review большого проекта, найти места, которые необходимо переписать. Также достаточно полезно следить за процессом изменения вышеописанных метрик. Это может показать руководителю об отношении программистов к разработке того или иного проекта, а также динамику изменения качества кода по каждому программисту, что немаловажно в нашей профессии. Другой причиной слежения за метриками, являются, определенные программистами, пороговые значения, при достижении которых, необходимо заняться рефакторингом.
Сегодня мы будем замерять производительность нашего приложения с помощью Visual Studio Profiling Tool.
Visual Studio Profiling Tool позволяет разработчикам измерять, оценивать производительность приложения и кода. Эти инструменты полностью встроены в IDE, чтобы предоставить разработчику беспрерывный контроль.
В этом руководстве мы по шагам профилируем приложение PeopleTrax используя Sampling и Instrumentation методы профилирования, чтобы выявить проблемы в производительности приложения.
Подготовка
Методы профилирования
Чуть-чуть отступим от главной темы статьи и рассмотрим возможные методы профилирования. Эту главу можно пропустить, используемые методы профилирования будут кратко описаны перед использованием.
Sampling
Sampling — собирает статистические данные о работе приложения (во время профилирования). Этот метод легковесный и поэтому, в результате его работы очень маленькая погрешность в полученных данных.
Каждый определенный интервал времени собирается информация о стеке вызовов (call stack). На основе этих данные производится подсчет производительности. Используется для первоначального профилирования и для определения проблем связанных с использование процессора.
Instrumentation
Instrumentation — собирает детализированную информацию о времени работы каждой вызванной функции. Используется для замера производительности операций ввода/вывода.
Метод внедряет свой код в двоичный файл, который фиксирует информацию о синхронизации (времени) для каждой функции в файл, и для каждой функции которые вызываются в этой.
- Elapsed Inclusive — общее время, затраченное на выполнение функции
- Application Inclusive — время, затраченное на выполнение функции, за исключением времени обращений к операционной системе.
- Elapsed Exclusive — время, затраченное на выполнение кода в теле. Время, которое тратят функции, вызванные целевой функцией.
- Application Exclusive — время, затраченное на выполнение кода в теле. Исключается время, которое тратится выполнения вызовов операционной системы и время, затраченное на выполнение функций, вызванные целевой функцией.
Concurrency
Concurrency – собирает информацию о многопоточных приложения (как отлаживать многопоточные приложения см. «Руководство по отладке многопоточных приложений в Visual Studio 2010»). Метод собирает подробную информацию о стеке вызовов, каждый раз, когда конкурирующие потоки вынуждены ждать доступа к ресурсу.
Tier Interaction
На этом рассмотрение методов профилирование закончим и продолжим учиться профилировать приложения.
Профилирование Sampling методом
Sampling это метод профилирования, который периодически опрашивает рассматриваемый процесс, чтобы определить активную функцию. В результате показывает количество раз, когда функция была в начале call stack во время тестирования.
Профилирование
Открываем тестовый проект PeopleTrax. Устанавливаем конфигурацию в Release (в Debug версию встраивается дополнительная информация для отладки приложения, и она плохо скажется на точности результатов профилирования).
В меню Analyze нажимаем на Launch Performance Wizard.
На этом шаге нужно выбрать метод профилирования. Выбираем CPU Sampling (recommended) и нажимаем Next.
Выбираем какое приложение мы будем профилировать, это PeopleTrax и кнопка Next. В следующем нажимаем Finish и автоматически запустится профайлер и наше приложение. На экране мы видим программу PeopleTrax. Нажимаем кнопку Get People, ждем завершения работы и Export Data. Закрываем блокнот и программу и профайлер сгенерирует отчет.
Профайлер сгенерировал отчет (*.vsp)
Анализ отчета Sampling метода
В Summary отображается график использования процессора в течение всего времени профилирования. Список Hot Path показывает ветки вызовов, которые проявили наибольшую активность. А в списке Functions Doing Most Individual Work (название которого говорит само за себя) – функции, которые занимали большее время процесса в теле этих функций.
Посмотрев на список Hot Path видим что метод PeopleNS.People.GetNames занимает почти последнее место в ветке вызовов. Его то и можно изучить внимательнее на предмет улучшения производительности. Нажимаем на PeopleNS.People.GetNames и перед нами открывается Function Details.
Это окно содержит две части. Окно расходов предусматривает графическое представление работы функций, и вклад функции и вызывающих ее на количество экземпляров, которые были отобраны. Можно изменить рассматриваемую функцию, нажав на нее мышкой.
Function Code View показывает код метода, когда он доступен и подсвечивает наиболее «дорогие» строки в выбранном методе. Когда выбран метод GetNames видно, что он читает строки из ресурсов приложения используя StringReader, добавляя каждую строку в ArrayList. Нет очевидных способов улучшить эту часть.
Так как PeopleNS.People.GetPeople единственный, кто вызывает GetNames – нажимаем GetPeople. Этот метод возвращает ArrayList объектов PersonInformationNS.PersonInformation с именами людей и компаний, возвращенными методом GetNames. Тем не менее, GetNames вызывается дважды каждый раз, когда создается PersonInformation. (Это и показано желтым и красным выделением). Очевидно, что можно легко оптимизировать метод, создавая списки только один раз вначале метода.
Оптимизированный метод заменит старый при следующей сборке.
Перезапускаем профилирование в текущей сессии нажав Launch with Profiling в окне Performance Explorer. Нажимаем на Get People и Export Data. Закрываем блокнот и программу а профайлер сгенерирует новый отчет.
Чтобы сравнить два отчета – выбираем оба и ПКМ Compare Performance Reports. Колонка дельты показывает разницу в производительности версии Baseline с более поздней Comparison. Выбираем Inclusive Samples % и Apply.
Как видно выигрыш в производительности заметен невооруженным глазом
Профилирование методом Instrumentation
Этот метод полезен при профилировании операций ввода вывода, запись на диск и при обмене данными по сети. Этот метод предоставляет больше информации чем предыдущий, но он несет с собой больше накладных расходов. Бинарники полученные после вставки дополнительного кода получаются больше обычных, и не предназначены для развертывания.
В этот раз мы сосредоточим наш анализ на экспорте данных, в котором список людей записывается в файл блокнота.
Профилирование
В Performance Explorer выбираем Instrumentation и нажмаем Start Profiling. Нажимаем Get People. После загрузки людей ждем 10 секунд и нажмаем Export Data. Закрываем блокнот и программу. Профилировщик сгенерирует отчет.
Анализ
Профилировщик покажет такую картинку:
Мы не получили ту информацию, которую хотели. Отфильтруем данные. Мы специально ждали 10 секунд, чтобы просто отфильтровать ненужные сейчас данные профилирования. Отмечаем с 13-й до конца и нажимаем Filter by selection. Уже другой результат:
Hot Path показывает, что метод Concat занимает много времени (он также первый в списке Functions With Most Individual Work). Нажимаем на Concat, чтобы посмотреть детально информацию о методе.
Видно, что PeopleTrax.Form1.ExportData – единственный метод, который вызывает Concat. Нажимаем PeopleTrax.Form1.ExportData в вызывающих методах (Function calling this function).
В проекте уже есть оптимизированный метод с использованием StringBuilder. В проекте PeopleTrax добавляем переменную компиляции OPTIMIZED_EXPORTDATA. Сохраняем и снова запускаем профайлер и сравниваем отчеты. Сразу видно (да и логически понятно) что мы оптимизировали вызовы Concat (с 6000 до 0 раз).
После запуска приложения на глаз видно заметное улучшение производительности. Очень важно запускать профилирование еще раз, даже есть видимые улучшения. Просмотр новых данных после исправления проблемы может показать другие проблемы в производительности приложений.
Читайте также: