Эмпирическое исследование корреляции между метриками кода, связанными с когнитивной сложностью

Lavazza L. An Empirical Study of the Correlation of Cognitive Complexity-related Code Measures // CSEA 2021: The Sixteenth International Conference on Software Engineering Advances, Barcelona, Spain, October 3–7, 2021: материалы конференции. — [S.l.]: IARIA, 2021. — ISBN 978-1-61208-894-5. — С. 1–6.

Luigi Lavazza

Dipartimento di Scienze Teoriche e Applicate, Università degli Studi dell’Insubria, Варезе, Италия

luigi.lavazza@uninsubria.it

Аннотация

Для представления различных характеристик кода — таких как размер, сложность, сцепленность (cohesion), связанность (coupling) и т. п. — предложено множество метрик. Эти метрики считаются важными, потому что измеряемые ими «внутренние» характеристики (сами по себе не столь интересные) предположительно коррелируют с «внешними» качествами программного обеспечения — например, надёжностью, сопровождаемостью и т. д., — которые действительно значимы для разработчиков и пользователей. Хотя для программного кода уже предложено немало метрик, новые продолжают появляться. Однако, прежде чем использовать очередную новую метрику, важно убедиться, что она действительно полезна и даёт улучшение по сравнению с хорошо зарекомендовавшими себя метриками, которые давно применяются и чьи достоинства широко изучены. В 2018 году была предложена новая метрика кода — «когнитивная сложность» (Cognitive Complexity). По словам её авторов, эта метрика должна гораздо лучше коррелировать с понятностью кода, чем «традиционные» метрики, например сложность Маккейба. Тем не менее практически не проводилось экспериментов, доказывающих, что «когнитивная сложность» лучше других метрик. Более того, даже не проверялось, даёт ли новая метрика иную информацию о коде по сравнению с «традиционными». В этой работе мы ставим целью экспериментально оценить, в какой мере новая метрика коррелирует с традиционными. Для этого мы измерили код набора открытых Java-проектов и построили модели «когнитивной сложности» на основе традиционных метрик кода, полученных с помощью современного инструмента измерений. Мы обнаружили, что достаточно точные модели «когнитивной сложности» можно получить, используя лишь несколько традиционных метрик. В этом смысле метрика «когнитивная сложность» не выглядит дающей дополнительную информацию по сравнению с ранее предложенными метриками.

I. Введение

Многие метрики были предложены для представления внутренних характеристик кода, таких как размер, сложность, сцепленность (cohesion) или связанность (coupling). Ряд эмпирических исследований установил связь этих метрик с внешними качествами ПО, представляющими интерес, например с дефектностью или сопровождаемостью.

Довольно часто появляются новые метрики. Некоторые из них нацелены на отражение специфических особенностей кода, которые ранее не учитывались: например, Чидамбер и Кемерер предложили число потомков (Number of Children, NOC) и глубину наследования (Depth of Inheritance, DIT) [1], когда объектно-ориентированные языки программирования начали набирать популярность.

Другие метрики предлагаются с конкретной целью — предсказывать интересные внешние качества. В 2018 году была предложена новая метрика, призванная отражать сложность понимания кода [2]. Эту метрику назвали «Cognitive Complexity» («когнитивная сложность»); однако далее в этой статье мы будем обозначать её как «CoCo», чтобы избежать путаницы с самим понятием когнитивной сложности, то есть свойством, которое CoCo должна измерять.

Некоторая начальная работа уже была выполнена, чтобы оценить, действительно ли CoCo коррелирует с понимаемостью кода [3]. Первые результаты этого исследования не подтверждают утверждение, что CoCo лучше коррелирует с понимаемостью кода, чем ранее предложенные метрики.

Как бы то ни было, независимо от того, достижению какой цели должна способствовать новая метрика, она должна давать такую «информацию», которую существующие метрики не способны зафиксировать. Если новая метрика настолько сильно коррелирует с другими, что по значениям последних можно построить модели, позволяющие с разумной точностью предсказывать значение новой метрики, то вряд ли эта метрика действительно несёт какие-то новые знания.

К CoCo сейчас проявляют определённое внимание, вероятно потому, что она доступна в SonarQube — весьма популярном инструменте. Поэтому настало время поискать свидетельства того, что CoCo даёт дополнительные сведения по сравнению с хорошо устоявшимися метриками кода. С этой целью в данной работе мы рассматриваем два исследовательских вопроса:

RQ1 Насколько сильно CoCo коррелирует с каждой из метрик кода, которые обычно используются в разработке программного обеспечения?

RQ2 Можно ли построить модели, предсказывающие значение CoCo на основе значений распространённых метрик кода? Если да, насколько точными оказываются такие предсказания?

Статья организована следующим образом. В Разделе II приводится краткая справка: вводится CoCo и описываются традиционные метрики кода, используемые в этом исследовании. В Разделе III описывается эмпирическое исследование, проведённое для ответа на исследовательские вопросы. В Разделе IV обсуждаются полученные результаты и даются ответы на исследовательские вопросы. В Разделе V рассматриваются угрозы валидности исследования. В Разделе VI приводятся связанные работы. Наконец, в Разделе VII формулируются выводы и намечаются направления будущей работы.

II. Метрики кода

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

Для количественной оценки свойств программных модулей были предложены различные метрики внутренних атрибутов ПО (например, размера, структурной сложности, сцепленности (cohesion), связанности (coupling)) [4]. Эти метрики представляют интерес, поскольку относятся к качествам кода, которые, как считается, влияют на внешние качества программного обеспечения (такие как дефектность или сопровождаемость), то есть на свойства, важные для разработчиков и пользователей.

Поскольку CoCo вычисляется на уровне метода, далее мы рассматриваем только метрики на том же уровне гранулярности, то есть метрики, применимые к методам.

A. «Традиционные» метрики кода

С момента появления первых языков программирования высокого уровня было предложено множество метрик для представления потенциально значимых характеристик кода. Например, Lines Of Code (LOC) измеряет размер программного модуля, а сложность Маккейба (также известная как цикломатическая сложность) [5] была предложена для представления «сложности» кода, исходя из идеи, что высокий уровень сложности характерен для кода, который трудно тестировать и сопровождать. Объектно-ориентированные метрики Чидамбера и Кемерера [1] были предложены для выявления плохого проектирования ПО. Например, считается, что модули с высоким уровнем связанности (coupling) труднее сопровождать.

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

Для сбора метрик кода использовался SourceMeter [6]. Перечень применённых метрик уровня метода приведён в Таблице I. В силу ограничений по объёму мы не можем дать здесь подробные определения каждой метрики; вместо этого приводим очень краткие описания. Заинтересованные читатели могут найти дополнительные сведения в документации SourceMeter.

Среди метрик, перечисленных в таб. 1, — метрики Хэлстеда [7]; несколько индексов сопровождаемости, включая исходный [8]; сложность Маккейба; метрики уровня вложенности (то есть того, насколько глубоко конструкции управления вложены одна в другую); логические строки кода (подсчитываемые без учёта пустых строк, строк, содержащих только комментарии, и т. п.).

Таблица 1. Метрики, собранные с помощью SourceMeter
Название метрики Сокращение
Halstead Calculated Program Length — расчетная длина программы HCPL
Halstead Difficulty — трудность HDIF
Halstead Effort — усилие HEFF
Halstead Number of Delivered Bugs — число доставленных дефектов HNDB
Halstead Program Length — длина программы HPL
Halstead Program Vocabulary — словарь программы HPV
Halstead Time Required to Program — время программирования HTRP
Halstead Volume — объем HVOL
Maintainability Index (Microsoft) MIMS
Maintainability Index (оригинальная версия) MI
Maintainability Index (SEI) MISEI
Maintainability Index (SourceMeter) MISM
Цикломатическая сложность Маккейба McCC
Уровень вложенности NL
Уровень вложенности «else-if» NLE
Логические строки кода LLOC
Число операторов NOS

B. Метрика «Cognitive Complexity»

В 2017 году компания SonarSource представила Cognitive Complexity [2] как новую метрику, предназначенную для оценки понятности произвольного фрагмента кода. Это название выбрано потому, что авторы исходили из предположения: метрика подходит для представления когнитивной сложности понимания кода. С этой целью CoCo была предложена с задачей «устранить недостатки цикломатической сложности и предложить измерение, которое точнее отражает относительную трудность понимания, а следовательно, и сопровождения методов, классов и приложений» [2].

Скорее индикатор, чем собственно метрика, CoCo учитывает несколько аспектов кода. Подобно сложности Маккейба, она принимает во внимание точки ветвления (условные операторы, циклы, конструкции switch и т. п.), но, в отличие от сложности Маккейба, назначает им вес, равный уровню вложенности плюс 1. Например, следующий фрагмент кода.


						void firstMethod() {
  							if (condition1)
    							for (int i = 0; i < 10; i++)
      								while (condition2) { ... }
						}
					

оператор if на уровне вложенности 0 имеет вес 1, оператор for на уровне вложенности 1 — вес 2, а оператор while на уровне вложенности 2 — вес 3; следовательно, CoCo = 1 + 2 + 3 = 6. Для этого же кода сложность по Маккейбу равна 4 (три точки ветвления плюс один).

Рассмотрим, напротив, следующий фрагмент кода, в котором управляющие конструкции не вложены друг в друга.


						void secondMethod() {
  							if (condition1) { ... }
  							for (int i = 0; i < 10; i++) { ... }
  							while (condition2) { ... }
						}
					

У этого кода CoCo = 3, тогда как его сложность по Маккейбу по-прежнему равна 4. Таким образом, очевидно, что вложенные конструкции повышают значение CoCo, тогда как на сложность Маккейба они не влияют.

CoCo также учитывает булевы предикаты: вклад булева предиката в CoCo зависит от числа его подпоследовательностей логических операторов. Например, рассмотрим следующий фрагмент кода, где a, b, c, d, e, f — булевы переменные.


						void thirdMethod() {
  							if (a && b && c || d || e && f) { ... }
						}
					

Предикат a && b && c || d || e && f содержит три подпоследовательности с одинаковыми логическими операторами, а именно: a && b && c, c || d || e и e && f, поэтому он добавляет 3 к значению CoCo.

Другие аспекты кода также могут увеличивать CoCo, но встречаются значительно реже, чем описанные выше. Полное описание CoCo приведено в определении [2].

III. Эмпирическое исследование

Эмпирическое исследование охватывало набор открытых Java-программ. Этот код был измерен, а собранные данные проанализированы с использованием хорошо устоявшихся статистических методов. Набор данных описан в Разделе III-A, а методы измерения и анализа — в Разделе III-B. Полученные результаты приведены в Разделе III-C.

A. Набор данных

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

Проекты, предоставившие код для исследования, перечислены в таб. 2, где также приведены некоторые описательные статистики по наиболее релевантным метрикам. Методы с CoCo=0 или NOS=0 явно не представляют интереса, поэтому их данные были исключены; соответственно, таб. 2 такие методы не учитывает. В целом исходный набор данных включал сведения по 13 922 методам. Набор данных доступен по запросу для целей воспроизведения.

Таблица 2. Описательная статистика наборов данных
Проект n Метрика mean st.dev. median min max
hibernate 2532 CoCo 3.1 4.3 2.0 1 79
HPV 32.3 17.1 28.0 0 211
MI 100.3 14.7 102.2 0 135
McCC 3.3 2.4 2.0 1 33
NLE 1.3 0.8 1.0 0 7
LLOC 15.2 12.3 12.0 3 201
jcaptcha 317 CoCo 3.3 4.0 2.0 1 34
HPV 35.0 18.4 29.0 10 120
MI 100.3 14.0 102.5 56 132
McCC 3.5 2.2 3.0 2 18
NLE 1.3 0.8 1.0 0 5
LLOC 14.6 10.6 11.0 3 80
jjwt 205 CoCo 4.0 7.2 2.0 1 84
HPV 30.6 22.9 28.0 0 280
MI 101.7 20.6 104.0 0 135
McCC 4.3 4.6 3.0 2 46
NLE 1.3 0.8 1.0 0 4
LLOC 13.5 14.9 11.0 3 169
json_iterator 379 CoCo 5.6 8.7 3.0 1 73
HPV 38.3 21.1 32.0 14 145
MI 96.4 15.3 99.0 45 131
McCC 4.6 3.9 3.0 1 28
NLE 1.6 1.0 1.0 0 7
LLOC 18.0 15.1 13.0 3 110
JSON-java 260 CoCo 5.7 15.8 2.0 1 203
HPV 41.0 36.9 31.5 11 413
MI 95.7 18.2 97.4 32 133
McCC 5.0 5.8 3.0 2 50
NLE 1.5 1.1 1.0 0 7
LLOC 21.5 26.5 13.0 3 255
log4j 798 CoCo 4.6 6.4 2.0 1 61
HPV 36.6 21.4 30.0 8 163
MI 98.1 15.2 100.4 44 135
McCC 4.1 3.4 3.0 1 34
NLE 1.6 1.0 1.0 0 8
LLOC 16.9 13.4 12.0 3 115
netty-socketio 136 CoCo 4.4 5.5 3.0 1 37
HPV 33.7 20.0 28.0 0 122
MI 97.7 20.8 101.4 0 132
McCC 4.1 2.8 3.0 1 19
NLE 1.6 0.9 1.0 0 5
LLOC 15.0 12.3 11.0 3 84
pdfbox 3587 CoCo 5.2 8.2 2.0 1 118
HPV 39.3 25.7 32.0 0 326
MI 93.7 17.2 96.4 0 128
McCC 4.5 4.5 3.0 1 58
NLE 1.6 1.1 1.0 0 10
LLOC 22.3 21.8 15.0 3 330
jasperreports 6415 CoCo 5.6 10.1 3.0 1 186
HPV 38.7 28.5 31.0 0 740
MI 93.4 18.1 96.5 0 132
McCC 4.9 5.6 3.0 1 117
NLE 1.6 1.1 1.0 0 10
LLOC 23.5 26.0 15.0 3 383

B. Методика

Первая фаза исследования заключалась в измерении кода. Для получения «традиционных» метрик мы использовали SourceMeter, а для измерения CoCo — собственный разработанный инструмент. Данные из обоих инструментов были объединены, в результате чего получен единый набор данных с 8 214 наблюдениями.

Второй шаг заключался в отборе данных для исследования. Мы исключили все методы со значением CoCo < 5, поскольку такие методы исказили бы результаты из-за «встроенных» зависимостей. Например, для фрагмента кода с CoCo=0 цикломатическая сложность по Маккейбу равна 1; аналогично, CoCo=1 обычно означает, что цикломатическая сложность Маккейба=2, и т. д. Кроме того, методы с низкой сложностью малоинтересны: поскольку CoCo предназначена для представления сложности понимания кода, она вряд ли полезна для настолько простых методов, что их понимание не вызывает трудностей. SonarQube [9] устанавливает порог для CoCo на уровне 15, то есть, по мнению SonarQube, CoCo < 15 — это «разумно безопасно». Поэтому, исключая лишь методы с CoCo < 5, мы уверены, что исключаем только «неинтересный» код. Мы также исключили методы с CoCo > 50, поскольку в нашем наборе данных таких методов слишком мало, чтобы обеспечить надёжный статистический анализ.

После исключения чрезмерно простых и чрезмерно сложных методов мы получили набор данных из 3 610 наблюдений, чего вполне достаточно для проведения значимого статистического анализа. В этом наборе среднее значение CoCo равно 12, а медиана — 9. Третий шаг заключался в выполнении статистического анализа. Мы начали с изучения корреляции между CoCo и каждой из прочих метрик кода. Поскольку данные не распределены нормально, мы использовали непараметрические методы: вычислили коэффициент ранговой корреляции Кендалла τ [10] и коэффициент ранговой корреляции Спирмена ρ [11]. Поскольку анализ корреляций дал обнадёживающие результаты, мы перешли к оценке связей как линейными, так и нелинейными методами. А именно, выполнили линейную регрессию методом наименьших квадратов (OLS) и регрессию OLS после логарифмического преобразования данных по схеме log–log. В обоих случаях выбросы выявлялись и исключались на основе расстояния Кука [12]. Во всех проведённых анализах результаты считались значимыми при стандартном уровне α = 0,05. Однако почти во всех случаях p-значения были существенно меньше.

C. Результаты исследования

Результаты корреляционных тестов Кендалла и Спирмена приведены в таб. 3. Все представленные результаты статистически значимы, p-значения существенно ниже 0,001.

Таблица 3. Результаты корреляционных тестов
Метрика τ ρ
HCPL 0.45 0.62
HDIF 0.38 0.52
HEFF 0.47 0.63
HNDB 0.47 0.63
HPL 0.50 0.67
HPV 0.46 0.62
HTRP 0.47 0.63
HVOL 0.50 0.66
MI -0.56 -0.73
MIMS -0.56 -0.73
MISEI -0.41 -0.57
MISM -0.41 -0.57
McCC 0.71 0.85
NL 0.50 0.61
NLE 0.50 0.60
LLOC 0.55 0.72
NOS 0.52 0.68

После оценки корреляций между CoCo и другими метриками мы перешли к построению регрессионных моделей. В результате после лог–лог-преобразования метрик мы получили 65 статистически значимых моделей. Ввиду ограничений по объёму мы не приводим их все; далее показаны только те, которые выглядят наиболее точными.

В таб. 4 приведено резюме найденных нами моделей. Для каждой модели указан скорректированный коэффициент детерминации R2 (полученный после исключения выбросов). Мы также даём несколько показателей точности моделей (вычисленных с учётом выбросов): MAR — среднее абсолютных остатков (т. е. средняя абсолютная ошибка предсказания), MMRE — средняя величина относительных ошибок, а MdMRE — медианная величина относительных ошибок. Поскольку MMRE и MdMRE считаются смещёнными индикаторами, мы приводим их лишь в дополнение к MAR, который рассматриваем как основной показатель точности [13].

Таблица 4. Найденные модели (зависимая переменная — CoCo)
Независимые переменные adjusted R2 MAR MMRE MdMRE
MI, NL 0.81 3.60 0.28 0.20
MIMS, NL 0.81 3.60 0.28 0.20
NLE, LLOC 0.79 3.08 0.25 0.20
HCPL, MI, NLE 0.84 2.96 0.24 0.18
HCPL, MIMS, NLE 0.84 2.96 0.24 0.18
HCPL, NLE, LLOC 0.81 3.04 0.25 0.20
HDIF, MI, NL 0.82 3.65 0.28 0.19
HDIF, MI, NLE 0.84 2.96 0.24 0.19
HDIF, MIMS, NL 0.82 3.65 0.28 0.19
HDIF, MIMS, NLE 0.84 2.96 0.24 0.19
HEFF, MI, NL 0.82 3.72 0.28 0.20
HEFF, MI, NLE 0.84 3.01 0.24 0.19
HEFF, MIMS, NL 0.82 3.72 0.28 0.20
HEFF, MIMS, NLE 0.84 3.01 0.24 0.19
HNDB, MI, NL 0.82 3.72 0.28 0.20
HNDB, MI, NLE 0.84 3.01 0.24 0.19
HNDB, MIMS, NL 0.82 3.72 0.28 0.20
HNDB, MIMS, NLE 0.84 3.01 0.24 0.19
HPL, MI, NLE 0.84 3.03 0.24 0.19
HPL, MIMS, NLE 0.84 3.03 0.24 0.19
HPL, NLE, LLOC 0.82 3.03 0.25 0.20
HPV, MI, NL 0.82 3.77 0.28 0.20
HPV, MI, NLE 0.84 2.95 0.24 0.18
HPV, MIMS, NL 0.82 3.77 0.28 0.20
HPV, MIMS, NLE 0.84 2.95 0.24 0.18
HTRP, MI, NL 0.82 3.72 0.28 0.20
HTRP, MI, NLE 0.84 3.01 0.24 0.19
HTRP, MIMS, NL 0.82 3.72 0.28 0.20
HTRP, MIMS, NLE 0.84 3.01 0.24 0.19
HVOL, MI, NLE 0.84 3.04 0.24 0.19
HVOL, MIMS, NLE 0.84 3.04 0.24 0.19
HVOL, NLE, LLOC 0.82 3.03 0.25 0.20
MI, MIMS, NLE 0.81 3.59 0.26 0.19
MI, NL, NLE 0.81 2.89 0.23 0.18
MI, NLE, LLOC 0.83 3.25 0.25 0.19
MIMS, NL, NLE 0.81 2.89 0.23 0.18
MIMS, NLE, LLOC 0.83 3.25 0.25 0.19
McCC, NLE, LLOC 0.95 1.77 0.15 0.11
McCC, NLE, McCC/LLOC 0.95 1.77 0.15 0.11
NL, NLE, LLOC 0.78 2.99 0.24 0.20
NLE, LLOC, McCC/LLOC 0.95 1.77 0.15 0.11

Отметим, что помимо метрик из таб. 1 мы также использовали MCC/LLOC, то есть плотность сложности Маккейба.

IV. Обсуждение

Результаты корреляционных тестов, приведённые в таб. 3, показывают, что CoCo коррелирует со всеми рассмотренными нами традиционными метриками кода. Особенно сильна корреляция CoCo со сложностью Маккейба; что примечательно, учитывая, что CoCo предлагалась как улучшение по отношению к сложности Маккейба.

Таким образом, на RQ1 можно ответить так:

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

Результаты, приведённые в таб. 4, позволяют ответить на RQ2 следующим образом:

Наше исследование показывает, что можно построить модели, предсказывающие значение CoCo по распространённым метрикам, а также с использованием метрик Хэлстеда и индексов сопровождаемости. Многие из полученных моделей демонстрируют весьма неплохую точность.

Примечательно, что независимые переменные, обеспечивающие наибольшую точность моделей, — это сложность Маккейба (MCC), уровень вложенности (NLE) и число логических строк кода (LLOC). Это неудивительно, поскольку элементы MCC и NLE входят в определение CoCo. Что касается LLOC, очевидно, что чем длиннее код, тем больше в нём (в среднем) точек ветвления; следовательно, можно ожидать, что LLOC также вносит вклад в CoCo. Фактически связь между CoCo и количеством строк кода уже отмечалась ранее [14].

В заключение, наше исследование показывает, что CoCo, по-видимому, не несёт больше информации, чем корректно подобранные наборы традиционных метрик кода, такие как MCC, NLE и LLOC.

V. УГРОЗЫ ВАЛИДНОСТИ

Что касается применения традиционных метрик, мы использовали современный, широко применяемый и зрелый инструмент SourceMeter, поэтому с этой стороны угроз не видим. CoCo измерялась с помощью специально разработанного инструмента, созданного на основе спецификации CoCo [2]. Этот инструмент был тщательно проверен с использованием SonarQube [9] в качестве эталона, поэтому мы достаточно уверены, что он даёт корректные измерения. Однако при объединении данных SourceMeter с данными нашего инструмента нам не всегда удавалось сопоставить идентификаторы методов, поскольку оба инструмента немного по-разному описывали имена методов, параметры и т. п. Мы просто исключили данные по тем методам, для которых не удалось найти надёжное соответствие: таким образом было потеряно менее 2% измерений. Поскольку утраченные метрики зависят от особенностей, не связанных со свойствами измеряемого кода, их можно считать случайной подвыборкой, которая вряд ли способна повлиять на итоги исследования.

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

VI. Связанные работы

Кэмпбелл провела исследование реакции разработчиков на внедрение CoCo в инструмент измерения и анализа SonarCloud [15 ]. Проанализировав 22 проекта с открытым исходным кодом, она оценивала, «приняла» ли команда метрику — по тому, исправляли ли разработчики участки кода, которые инструмент пометил как имеющие высокое значение CoCo. Около 77% разработчиков выразили принятие метрики.

Объективную валидацию метрики CoCo выполнили Muñoz Barón и соавт. [3]. Они собрали наборы данных из опубликованных исследований, где понятность исходного кода измерялась с позиции человеческих разработчиков. Были собраны данные, касающиеся различных аспектов понятности, а также фрагменты кода, использованные в экспериментах. Для каждого фрагмента кода они получили значение CoCo с помощью SonarQube [9], после чего вычислили корреляцию CoCo с показателями разных аспектов понятности. Muñoz Barón и соавт. представили корреляции между CoCo и разными аспектами понятности по каждому из 10 экспериментов в выбранных работах, а также сводку, полученную методом мета-анализа. Их вывод: CoCo умеренно коррелирует с некоторыми из рассматриваемых аспектов понятности.

Упомянутая выше работа оценивала результативность CoCo (метрики внутренних свойств кода) как индикатора понятности (внешнего свойства кода). Насколько нам известно, никто не проводил анализа, рассматривающего, как только внутренние свойства кода коррелируют с CoCo. Тем не менее CoCo использовалась в ряде оценок. Поскольку CoCo поставляется в составе SonarQube [9 ] наряду с множеством других метрик и индикаторов, некоторые исследователи, применявшие SonarQube для сбора метрик кода, включали CoCo в анализ вместе с другими метриками. Ниже перечислены некоторые работы, в которых использовалась CoCo.

Козик и соавт. [14] разработали фреймворк для анализа зависимости качества программного обеспечения от метрик кода и других данных. Применив свой фреймворк, они обнаружили, что CoCo влияет на анализируемость и адаптируемость кода.

Пападопулос и соавт. [16] исследовали взаимосвязь между метриками качества на этапе проектирования и метриками качества времени выполнения, такими как промахи кэша, обращения к памяти, память, занимаемая программой, и такты ЦП. Они наблюдали компромисс между производительностью/энергопотреблением и когнитивной сложностью. Однако, поскольку в качестве единственной метрики качества на стадии проектирования использовалась CoCo, неизвестно, проявился бы тот же компромисс и для других проектных метрик, например для сложности Маккейба. Наше исследование позволяет считать эти сомнения обоснованными.

Креспо и соавт. [17] использовали как показатель «Cognitive complexity rate» (определяется как CoCo/LOC), так и «Cyclomatic complexity rate» (определяется как сложность Маккейба/LOC) в составе стратегии оценки технического долга в образовательном контексте. Они обнаружили, что «Cognitive complexity rate» и «Cyclomatic complexity rate» дают одинаковые результаты — или, точнее, одинаковое отсутствие результатов. Учитывая сильную корреляцию между CoCo и сложностью Маккейба, которую мы наблюдали, результат Креспо и соавт. не удивителен.

VII. Заключение

Метрика «Cognitive Complexity» (далее — CoCo) была предложена с целью улучшить возможности сложности Маккейба в указании на код, который трудно понимать и сопровождать [2]. CoCo — скорее индикатор, чем полноценная метрика: её определение учитывает ряд характеристик исходного кода. Среди них — число точек принятия решений (например, операторы if, for, while и switch) и уровень вложенности управляющих конструкций.

На момент появления CoCo не было опубликовано оценок, рассматривающих связь CoCo с традиционными метриками, которые напрямую отражают упомянутые характеристики кода. В данной работе мы представили эмпирическое исследование, направленное на оценку корреляции между CoCo и несколькими традиционными метриками, включая те, что учитывают те же свойства кода, что и CoCo. Для этого мы измерили код нескольких проектов с открытым исходным кодом, получив метрики для 3 610 методов, а затем провели статистический анализ с использованием как корреляционных тестов (в частности, ранговых коэффициентов Кендалла и Спирмена), так и регрессионного анализа.

Мы обнаружили, что CoCo сильно коррелирует со сложностью Маккейба и несколько слабее — с рядом других метрик кода. Были получены несколько регрессионных моделей CoCo как функции традиционных метрик. Неудивительно, что одна из самых точных моделей включает сложность Маккейба (MCC), NLE (Nesting Level Else-If — уровень вложенности с ветвлениями else-if) и LLOC (число логических строк кода) в качестве независимых переменных. Учитывая, что для наиболее точных моделей MAR = 1,7 при среднем значении CoCo, равном 12, можно заключить, что — по крайней мере для рассмотренных программных проектов — CoCo, по-видимому, не несёт дополнительной информации по сравнению с традиционными метриками.

В итоге представленное исследование наводит на мысль, что CoCo не предоставляет сколь-нибудь существенного нового знания по сравнению с метриками кода, традиционно ассоциируемыми с понятием сложности.

Мы планируем продолжить работу: 1) проанализировать дополнительный код; 2) использовать иные статистические инструменты (например, метод главных компонент); 3) применить методы машинного обучения.

Благодарности

Работа, представленная здесь, частично поддержана фондом Fondo per la Ricerca di Ateneo, Университет degli Studi dell’Insubria.

Автор благодарит Анатолия Рошку за разработку инструмента, использованного для измерения CoCo.

Литература

  1. S. R. Chidamber and C. F. Kemerer, “A metrics suite for object oriented design,” IEEE Transactions on software engineering, vol. 20, no. 6, 1994, pp. 476–493.
  2. G. A. Campbell, “Cognitive complexity - a new way of measuring understandability,” https://www.sonarsource.com/docs/CognitiveComplexity. pdf, 2018, [Online; accessed 7-September-2021].
  3. M. M. Baron, M. Wyrich, and S. Wagner, “An empirical validation of ? cognitive complexity as a measure of source code understandability,” in Proceedings of the 14th ACM/IEEE International Symposium on Empirical Software Engineering and Measurement (ESEM), 2020, pp. 1–12.
  4. N. Fenton and J. Bieman, Software metrics: a rigorous and practical approach. CRC press, 2014.
  5. T. J. McCabe, “A complexity measure,” IEEE Transactions on software Engineering, no. 4, 1976, pp. 308–320.
  6. “SourceMeter,” https://www.sourcemeter.com/, [Online; accessed 7- September-2021].
  7. M. H. Halstead, Elements of software science. Elsevier North-Holland, 1977.
  8. P. Oman and J. Hagemeister, “Metrics for assessing a software system’s maintainability,” in Proceedings Conference on Software Maintenance 1992. IEEE Computer Society, 1992, pp. 337–338.
  9. “SonarQube,” https://www.sonarqube.org/, [Online; accessed 7- September-2021].
  10. M. G. Kendall, “Rank and product-moment correlation,” Biometrika, 1949, pp. 177–193.
  11. C. Spearman, “The proof and measurement of association between two things,” The American journal of psychology, vol. 100, no. 3/4, 1987, pp. 441–471.
  12. R. D. Cook, “Detection of influential observation in linear regression,” Technometrics.
  13. M. Shepperd and S. MacDonell, “Evaluating prediction systems in software project estimation,” Information and Software Technology, vol. 54, no. 8, 2012, pp. 820–827.
  14. R. Kozik, M. Choras, D. Puchalski, and R. Renk, “Q-rapids framework ' for advanced data analysis to improve rapid software development,” Journal of Ambient Intelligence and Humanized Computing, vol. 10, no. 5, 2019, pp. 1927–1936.
  15. G. A. Campbell, “Cognitive complexity: An overview and evaluation,” in Proceedings of the 2018 International Conference on Technical Debt, 2018, pp. 57–58.
  16. L. Papadopoulos, C. Marantos, G. Digkas, A. Ampatzoglou, A. Chatzigeorgiou, and D. Soudris, “Interrelations between software quality metrics, performance and energy consumption in embedded applications,” in Proceedings of the 21st International Workshop on software and compilers for embedded systems, 2018, pp. 62–65.
  17. Y. Crespo, A. Gonzalez-Escribano, and M. Piattini, “Carrot and stick approaches revisited when managing technical debt in an educational context,” arXiv preprint arXiv:2104.08993, 2021.