Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Ответы на госэкзамен / качество ПО

.doc
Скачиваний:
22
Добавлен:
02.05.2014
Размер:
67.58 Кб
Скачать

6

Здесь Вы найдете ответы на вопросы 19, 20

Качество программного продукта

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

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

Критериями качества ПП являются:

  • функциональность;

  • надежность;

  • легкость применения;

  • эффективность;

  • сопровождаемость;

  • мобильность.

Функциональность – это способность ПП выполнять набор функций, определенных его внешними спецификациями.

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

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

Эффективность – это отношение уровня услуг, предоставляемых ПП к объему используемых вычислительных ресурсов. Напомню, что объем используемых вычислительных ресурсов количественно определяется затратами машинного времени и оперативной памяти на выполнение заданных функций.

Обращаю ваше внимание на то, что тестирование программ более объемно, чем мы с вами рассматривали. Тестирование включает три аспекта проверки программ: на правильность (именно этому аспекту были посвящены лекции по тестированию); на вычислительную сложность и на эффективность реализации. Проверка вычислительной сложности заключается в экспериментальном анализе сложности программы или экспериментальном сравнении двух или нескольких алгоритмов, решающих одну и туже задачу. Этой проблемой, в основном, занимается вычислительная математика. Проверка эффективности реализации направлена на отыскание способа заставить правильную программу (правильную в смысле удовлетворения первому аспекту проверки) работать быстрее или расходовать меньше памяти. “Или” здесь свидетельствует о том, что показатели объема используемой памяти и времени выполнения противоречивы! Короткая программа иногда выполняется дольше более длинной программы! / 1,3/.

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

Мобильность – это способность ПП быть перенесенным из одной вычислительной среды (окружения) в другую, в частности, с одной ЭВМ на другую (применяют термин “перенос с одной платформы на другую”).

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

Эффективность

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

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

Не следует забывать и о том, что многие способы снижения временных затрат приводят к увеличению емкостных и, наоборот, уменьшение объема памяти может потребовать дополнительного времени на обработку. И тем более не следует «платить» за увеличение эффективности снижением технологичности разрабатываемого программного обеспечения. Исключения возможны лишь при очень жестких требованиях и наличии соответствующего контроля за качеством.

Частично проблему эффективности программ решают за программиста компиляторы. Средства оптимизации, используемые компиляторами, делят на две группы:

машинно-зависимые, т. е. ориентированные на конкретный машинный язык, выполняют оптимизацию кодов на уровне машинных команд, например, исключение лишних пересылок, использование более эффективных команд и т.п.;

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

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

Способы экономии памяти. Принятие мер по экономии памяти предполагает, что в каких-то случаях эта память неэкономно использовалась. Учитывая, что анализировать имеет смысл только операции размещения данных, существенно влияющие на характеристику эффективности, следует обращать особое внимание на выделение памяти под данные структурных типов (массивов, записей, объектов и т. п.).

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

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

Также следует помнить, что при передаче структурных данных в подпрограмму «по значению» копии этих данных размещаются в стеке. Избежать копирования иногда удается, если передавать данные «по ссылке», но как неизменяемые (описанные const). В последнем случае в стеке размещается только адрес данных, например:

Type Massiv=array[1..100] of real;

function Summa(Const a:Massiv; ...)...

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

Первый способ связан с учетом времени выполнения операций в ЭВМ:

  • сложение и вычитание выполняются быстрее, чем умножение и деление (в связи с чем Х+Х выполняется быстрее, чем 2*Х);

  • целочисленная арифметика быстрее арифметики вещественных чисел (поэтому (i+i+j)*0,5 быстрее, чем i+0,5*j, т.к. в первом варианте одна операция с вещественными числами, а во втором – две);

  • в целочисленной арифметике операции умножения или деления на числа, кратные 2, можно заменить соответствующим количеством сдвигов (например, умножение 10А можно заменить на

  • A SHL 3+A SHL 1, что потребует меньшего процессорного времени)

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

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

При их написании необходимо по возможности:

• выносить вычисление константных, т. е. не зависящих от параметров цикла, выражений из циклов;

• избегать «длинных» операций умножения и деления, заменяя их сложением, вычитанием и сдвигами;

• минимизировать преобразования типов в выражениях;

• оптимизировать запись условных выражений - исключать лишние проверки;

• исключать многократные обращения к элементам массивов по индексам (особенно многомерных, так как при вычислении адреса элемента используются операции умножения на значение индексов) - первый раз прочитав из памяти элемент массива, следует запомнить его в скалярной переменной и использовать в нужных местах;

• избегать использования различных типов в выражении и т. п.

Рассмотрим следующие примеры.

Пример 1. Пусть имеется цикл следующей структуры (Pascal):

for у: =0 to 99 do

for x:=0 to 99 do

a[320*x + y]:=S[k,l];

В этом цикле операции умножения и обращения к элементу S[k,l] выполняются 10000 раз. Оптимизируем цикл, используя, что 320 = 28 + 26:

В результате вместо 10000 операций умножения будут выполняться 200 операций сдвига, а их время приблизительно сравнимо со временем выполнения операции сложения. Обращение к элементу массива S[k,l] будет выполнено один раз.

Пример 2. Пусть имеется цикл, в теле которого реализовано сложное условие:

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

Пример 3. В некоторых случаях время выполнения программы можно уменьшить за счет исключение циклов, например во фрагменте:

For I:=1 to 1000 do

A[I]:=0;

For I:=1 to 1000 do

For j:=1 to 1000 do

A[I]:= A[I]+C[I,j];

можно отказаться от одного цикла:

For I:=1 to 1000 do begin

B:=A[I];

For j:=1 to 1000 do

B:= B+C[I,j];

A[I]:=B

end.

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

Пример 4. Иногда отказ от вложенного цикла может дать экономию времени выполнения программы. Например, запись:

For I:=1 to 1000 do

For j:=1 to 3 do

A[I]:= A[I]+C[I,j];

Можно переписать так:

For I:=1 to 1000 do

A[I]:= A[I]+C[I,1] +C[I,2] +C[I,3].

Выигрыш в скорости вычислений во втором варианте очевиден.

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

Предлагаю Вам самостоятельно найти самый быстрый вариант вычисления корней квадратного уравнения и доказать это /4/.

Соседние файлы в папке Ответы на госэкзамен