Вход/Регистрация
Программирование на языке Ruby
вернуться

Фултон Хэл

Шрифт:

Командную утилиту

rcov
(и соответствующую библиотеку) написал Маурисио Фернандес (Mauricio Fernandez). Устанавливается она в виде gem-пакета.

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

rcov myfile.rb

Одновременно с исполнением вашей программы

rcov
будет собирать статистику. По умолчанию она создает каталог
coverage
, в котором вы найдете HTML-файлы. В файле
index.html
представлены сводные результаты и ссылки на исходные тексты, где строки, которые хотя бы раз исполнялись, подсвечены.

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

Хотя программа

rcov
полезна даже в стандартном режиме, она понимает порядка 30 различных параметров. Можно указать каталог для выходных файлов, образцы имен файлов, для которых собирать и не собирать статистику, задать режим сортировки по именам файлов и многое другое. Можно выводить результаты в текстовом виде и даже запросить цветную диаграмму покрытия. Рекомендую прочитать поставляемую документацию, запросить справку командой
rcov -h
и… получать удовольствие.

Можно использовать

rcov
и в качестве библиотеки для написания аналогичных инструментов анализа. Ее API состоит из трех основных классов:

• 

Rcov::FileStatistics
позволяет отличить исполняемые предложения от комментариев (и тем самым уточнить статистику покрытия);

• 

Rcov::CodeCoverageAnalyzer
применяется для трассировки выполнения, возвращает информацию о покрытии и счетчики выполненных предложений;

• 

Rcov::CallSiteAnalyzer
нужен для того, чтобы понять, где определены методы и откуда они вызываются.

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

16.6. Измерение производительности

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

Конечно, быстродействие имеет значение. Иногда даже очень большое. Однако начинать думать об этом на раннем этапе цикла разработки — ошибка. Как говорится, «преждевременная оптимизация — источник всех зол»; эту мысль впервые высказал Хоар (Hoare), а потом подтвердил Кнут (Knuth). Или, перефразируя, сначала пусть работает правильно, а уж потом быстро». На уровне отдельного приложения эта рекомендация обычно оказывается хорошим эвристическим правилом, хотя для больших систем она, быть может, и не так актуальна.

Я бы еще добавил: «Не оптимизируйте, пока не измерите».

Это не такое уж серьезное ограничение. Просто не приступайте к переработке ради скорости, пока не ответите на два вопроса: «Действительно ли программа работает медленно? Какие именно ее части снижают производительность?»

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

Нам нужны объективные измерения. Профилировщик нужен.

В комплект поставки Ruby входит профилировщик

profile
. Для его вызова достаточно включить библиотеку:

ruby -rprofile myprog.rb

Рассмотрим листинг 16.6. Эта программа открывает файл

/usr/share/dict/words
и ищет в нем анаграммы. Затем смотрит, у каких слов оказалось больше всего анаграмм, и распечатывает их.

Листинг 16.6. Поиск анаграмм в словаре

words = File.readlines("/usr/share/dict/words")

words.map! {|x| x.chomp }

hash = {}

words.each do |word|

 key = word.split("").sort.join

 hash[key] ||= []

 hash [key] << word

end

sizes = hash.values.map {|v| v.size }

most = sizes.max

list = hash.find_all {|k,v| v.size == most }

puts "Ни у одного слова нет более #{most-1} анаграмм."

list.each do |key,val|

 anagrams = val.sort

 first = anagrams.shift

 puts "Слово #{first} имеет #{most-1) анаграмм:"

 anagrams.each {|a| puts " #{a}" }

end

num = 0

hash.keys.each do |key|

 n = hash[key].size

 num += n if n > 1

end

puts

  • Читать дальше
  • 1
  • ...
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: