Сколько нужно программистов, чтобы поддерживать ранее написанный код?

Некоторое время назад между мной и моим хорошим другом состоялся разговор, в котором прозвучали такие фразы:

— Количество программистов будет постоянно расти — ведь количество кода растет, и для его поддержки постоянно требуется все больше разработчиков.
— Но код стареет, часть его уходит из поддержки. Не исключено даже наличие какого-то равновесия.

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

Вопрос первый. Может ли поддержка «съесть» все ресурсы разработки?


Рассмотрим коллектив программистов, в котором число участников постоянно. Доля их рабочего времени $\mu(t)$ ($0<\mu(t)<1$) приходится на разработку нового кода, а оставшаяся доля времени $1-\mu(t)$ уходит на поддержку. В рамках допущений модели предположим, что первый вид деятельности направлен на увеличение объёма кода, а второй — на его изменение (исправление ошибок) и существенного влияния на объём кода не оказывает.

Обозначим $y(t)$ весь объём кода, написанный к моменту времени $t$. Считая скорость написания кода пропорциональной $\mu(t)$, получаем:

$\frac{dy(t)}{dt}=a_0 \mu(t); a_0\in \mathbb{R}, a_0 > 0.$» /></p>

<p><br />Естественно предположить, что трудозатраты на поддержку кода пропорциональны его объёму: </p>

<p><img src=


Откуда

$\frac{dy(t)}{dt}=a_0 (1-a_1y(t))).$


Получаем дифференциальное уравнение, которое легко интегрируется. Если в начальный момент времени объем кода равен нулю, то

$y(t)=\frac{1}{a_1}(1-e^{-a_0a_1t}).$


При $t\to+\infty$ функция $y(t)\to1/a_1$, а $\mu(t)\to 0$. И это означает постепенное сокращение с течением времени разработки нового функционала до нуля и переход всех ресурсов на поддержку.

Однако, если за время $h>0$» /> код устаревает и перестаёт поддерживаться, то объём кода, требующего поддержки, в момент времени <img src= равен уже $y(t) - y(t-h).$ Тогда

$1-\mu(t)=a_1 (y(t) - y(t-h)),$

$\mu(t)=1-a_1(y(t) - y(t-h)),$


а $y(t)$ является решением дифференциального уравнения с запаздывающим аргументом [1]:

$\frac{dy(t)}{dt}=a_0 (1-a_1(y(t) - y(t-h))).$


Решение такого уравнения однозначно определяется заданием значений $y(t)$ «до начала времён», при $t\in [-h, 0]$. Так как до начального момента времени кода написано ещё не было, то в нашем случае $y(t)=0$ при $t\in[-h, 0]$.

Рассмотрим несколько примеров. Будем измерять время в годах, а объём кода в тысячах строк. Тогда для $a_0$ приемлемыми являются значения порядка десятков, мы возьмём 50 и 100. То есть за год группа разработки напишет пятьдесят и сто тысяч строк кода соответственно. Для $a_1$ приемлемыми могут быть величины: $0.25/a_0$, $0.5/a_0$, $1/a_0$. Это означает, что группа разработчиков способна поддерживать объём кода, который написан ей же за год, при занятости на четверть, на половину или для этого требуется полная занятость. В качестве среднего времени жизни кода зададимся величинами: 1, 2 и 4 года. Решая уравнение численно, получим примеры поведения функции $\mu(t)$ для некоторых комбинаций параметров $h, a_0, a_1$.
image
Характер поведения функции $\mu(t)$ в условиях старения кода изменился. Функция перестала быть монотонной, но колебания со временем «успокаиваются», наблюдается тенденция стремления $\mu(t)$ к некоторому постоянному значению. Графики показывают: чем больше $h$, $a_0$ и $a_1$, то есть чем медленнее стареет код, чем быстрее происходит разработка нового кода и чем ниже качество кода, тем меньше ресурсов будет оставаться для разработки нового функционала. Было желание привести хотя бы один пример, в котором $\mu(t)$ «прижалась» близко к нулю. Но это потребовало подбора очень плохих показателей качества разработки и долго не стареющего кода. Даже на левом нижнем графике на новый функционал остается ощутимое количество ресурсов. Поэтому правильный ответ на первый вопрос скорее такой: теоретически — да, это возможно; практически — вряд ли.

Вопросы, на которые не удалось получить ответ:

  1. Верно ли, что $\mu(t)$ стремится к некоторому пределу при $t\to+\infty$ для всех $a_0, a_1 > 0$» />? Если не для всех, то для каких? </li>
<li> Если предел существует, то как его значение зависит от <img src=?


Вопрос второй. Может ли поддержка кода стать причиной неограниченного роста количества программистов?


Обозначим $q(t)$ количество программистов, занятых разработкой нового кода. Как и выше, $y(t)$ — объём кода, написанного к моменту времени $t$. Тогда

$\frac{dy(t)}{dt}=a_2 q(t); a_2\in \mathbb{R}, a_2 > 0.$» /></p>

<p><br />Пусть поддержкой кода заняты <img src= программистов. C учётом старения кода,

$p(t)=a_3(y(t)-y(t-h));a_3\in \mathbb{R}, a_3>0.$» /></p>

<p><br />Откуда</p>

<p><img src=


Если $q(t)\leq C_1$, то 

$p(t)\leq a_1a_2C_1h.$


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

Заключение


Рассмотренные модели являются «мягкими» математическими моделями [2]. Они очень просты. Тем не менее, зависимость результатов моделирования от значений параметров соответствует ожидаемой для реальных систем, это говорит в пользу адекватности моделей и достаточной точности для получения качественных оценок.

Список литературы


1. Эльсгольц Л.Э., Норкин С.Б. Введение в теорию дифференциальных уравнений с отклоняющимся аргументом. Москва. Издательство «Наука». 1971.
2. Арнольд В.И. «Жесткие» и «мягкие» математические модели. Москва. Издательство МЦНМО. 2004.

© Habrahabr.ru