exponenta event banner

Снижение сложности программного обеспечения с помощью средств проверки в полиспейсе

Сложность программного обеспечения относится к различным количественным метрикам программного модуля или исходных файлов, таким как количество строк, количество путей, количество функций или сложность дерева вызова функции. Проверка сложности программного обеспечения Polyspace ® повышается, когда эти показатели превышают пороговое значение. Высокая сложность программного обеспечения может указывать на сложность чтения, понимания и отладки кода. Более эффективно поддерживать приемлемый уровень сложности программного обеспечения во время разработки вместо рефакторинга сложных проектов в дальнейшем. Используйте средства проверки сложности программного обеспечения для обнаружения сложных модулей на ранних этапах цикла разработки, чтобы сократить последующие усилия по рефакторингу.

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

Настройка пороговых значений для проверки сложности программного обеспечения

Каждая проверка сложности программного обеспечения соответствует метрике сложности. Polyspace поднимает средство проверки сложности программного обеспечения, когда соответствующая метрика сложности кода превышает пороговое значение.

Пороговые значения по умолчанию для этих шашек соответствуют стандарту сложности кода Hersteller Initiative Software (HIS). См. раздел Показатели сложности кода HIS. Для шашек, отсутствующих в стандарте HIS, пороговые значения по умолчанию достаточно высоки, чтобы показатели сложности кода всегда были ниже порогового значения. Чтобы эффективно использовать эти шашки, укажите для них соответствующий порог.

Определите соответствующий набор пороговых значений для этих шашек в зависимости от оптимальной практики для сценария использования. Например, при анализе новых проектов или недавно разработанного кода может потребоваться сократить использование GOTO операторов путем установки порогового значения Number of goto statements exceeds threshold до нуля. При анализе модулей, содержащих старые библиотеки, может потребоваться установить пороговое значение большего числа.

В зависимости от продукта Polyspace укажите пороговое значение с помощью интерфейса пользователя или интерфейса командной строки. Например:

Определение и снижение сложности программного обеспечения

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

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

Пороговые значения указывают на приемлемый уровень сложности программного обеспечения. Чтобы выявить проблемы в коде, которые могут привести к повышению уровня сложности, после настройки средств проверки сложности программного обеспечения выполните анализ Polyspace Bug Finder. Рассмотрим этот код:

 long long power(double x, int n){
	 long long BN = 1;
	 for(int i = 0; i<n;++i){
		 BN*=x;
	 }
	 return BN;
 }
 
 double AppxIndex(double m, double f){//Noncompliant
	 double U = (power(m,2) - 1)/(power(m,2)+2);
	 double V = (power(m,4) + 27*power(m,2)+38)/(2*power(m,2)+3);
	 return (1+2*f*power(U,2)*(1+power(m,2)*U*V+ power(m,3)
	         /power(m,3)*(U-V)))/( (1-2*f*power(U,2)*(1+power(m,2)*U*V 
	        + power(m,3)/power(m,3)*(U-V))));
 }
Функция AppxIndex выглядит сложным. Неочевидно, как можно уменьшить сложность. Проверки сложности программного обеспечения помогают определить источники сложности.

После анализа Bug Finder настраиваемые шашки поднимаются:

  • Comment density below thresholdФункции в кодексе не содержат пояснительных замечаний.

  • Call tree complexity exceeds threshold и Number of call occurrences exceeds threshold: Слишком много вызовов функций по сравнению с количеством определений функций. Эти проверки показывают, что некоторые выражения можно упаковывать в отдельные функции.

  • Language scope exceeds threshold: Один и тот же операнд повторяется несколько раз. Можно уменьшить количество повторений. Например, функция power вызывается с одинаковыми аргументами несколько раз.

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

Снижение сложности программного обеспечения

Уменьшите сложность кода, решив выявленные проблемы. В этом случае основной причиной повышенных проверок является то, что функция AppxIndex выполняет несколько задач вместо выполнения одной задачи. Например, функция сначала вычисляет U, затем вычисляет Vи, наконец, вычисляет длинное выражение, содержащее оба U и V. Для решения этих проблем выполните рефакторинг функции. AppxIndex чтобы каждая задача была делегирована отдельной функции. Можно разбить длинное выражение на более мелкие части. Например:

// This code calculates effective index of materials  as described in
// the formula in 10.1364...
// power(x,n) returns the nth power of x (x^n)
// n is an integer
// x is a double
// return type is long long

long long power(double x, int n){//Compliant
	long long BN = 1;
	for(int i = 0; i<n;++i){
		BN*=x;
	}
	return BN;
}
// CalculateU(m) calculates the first intermediate variable
// required to calculate  polarization
// m is the relative refractive index
// return type is double;

double CalculateU(double m){//Compliant
	return (power(m,2) - 1)/(power(m,2)+2);
}
// CalculateV(m) calculates the second intermediate variable
// required to calculate  polarization
// m is the relative refractive index
// return type is double;

double CalculateV(double m){//Compliant
	return (power(m,4) + 27*power(m,2)+38)/(2*power(m,2)+3);
}
// CalculateMid(m,f) calculates the large term present 
// in both numerator and denominator
// of the effective index calculation
// m is the relative refractive index
// f is the fillfactor 
// return type is double;

double CalculateMid(double m, double f){//Compliant
	double U = CalculateU(m);
	double V = CalculateU(m); 
	return 2*f*power(U,2)*(1+power(m,2)*U*V + power(m,3)/power(m,3)*(U-V));
}
//AppxIndex(m,f) calculates the approximate effective index
// m is the relative refractive index
// f is the fillfactor
//return type is double
double AppxIndex(double m, double f){//Compliant
	return (1+CalculateMid(m,f))/( (1-CalculateMid(m,f)));
}
В этом коде ни одна из проверок сложности программного обеспечения не поднимается, что указывает на снижение сложности этого кода до приемлемого уровня. Для уменьшения сложности программного обеспечения:

  1. Документирование кода с достаточными комментариями.

  2. Разбейте большую сложную задачу, выполняемую AppxIndex на более мелкие и простые задачи, которые затем делегируются отдельным функциям, таким как CalculateU, CalculateV и CalculateMid. Функция power теперь называется реже. Если позже реализовать другую функцию для вычисления мощности и использовать новую функцию вместо текущей, придется сделать меньше замен.

  3. Запишите новые функции для выполнения одной конкретной задачи с минимальным перекрытием их функциональных возможностей. В результате эти функции содержат меньше повторений одних и тех же операндов.

Дополнительные сведения о проверке сложности программного обеспечения см. в документации средства проверки.

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

Связанные темы