пятница, 7 марта 2008 г.

Ruby On Rails

После того, как я начал разбираться и использовать Ruby, я пришёл к мысли, что было бы неплохо разобраться и с Ruby On Rails - вэб-фрэймворком, который является важной движущей силой распространения языка. Как оказалось, разобраться с RoR совсем не просто. Этот фреймворк обладает значительным когнитивным сопротивлением. Хотя в определённой степени проблемы возникают из-за того, что для последней версии Rails ещё не появилось достаточно хороших туториалов, а старые не работают. Удалось найти только одну книгу, ориентированную на RoR 2.0 - Rails Way by Obie Fernandez. Это примерно 900 страниц на английском. На следующей неделе попробую взяться за эту книгу.

вторник, 19 февраля 2008 г.

Оптимизация кода

Сегодня удалось добиться примерно десятикратного ускорения работы моего парсера. Проблема вообще возникла из-за того, что я относился к обработке строк в С/С++ стиле - преобразовывал строку с массив символов и переберал их для нахождения начала и окончания блоков. Делать это на Ruby - далеко не лучшая идея. На языке высокого уровня нет смысла использовать низкоуровневый подход. Если в С при переборе символов строки достаточно инкрементировать значение указателя, то здесь будет создан(а затем и уничтожен) объект для каждого символа. В общем совершенно ничего хорошего. Поэтому использовавние функции String#index с простейшим регекспом даёт значительный эффект. Что конечно же не может не радовать.
Для обзначения начала и окончания блоков используются символы '{' и '}'. Для поиска конца блока использовалась следующая функция


def find_end(str)
arr = str.split(//)
open_count = 0
close_count = 0
pos = 0
arr.each do |x|
open_count += 1 if(x == "{")
close_count += 1 if(x == "}")
if(open_count == close_count)
return pos
end
pos += 1
end
nil
end


Теперь эта функция выглядит так:

def find_end(str)
open_count = 0
close_count = 0
pos = 0
while(pos != nil)
pos = str.index(/\{|\}/, pos)
if(pos != nil)
open_count += 1 if str[pos] == 123
close_count += 1 if str[pos] == 125
end
if(open_count == close_count)
return pos
end
pos += 1
end
nil
end


Вероятно этот код можно ещё ускорить, но я пока не знаю как. Кроме ускорения за счёт оптимального использования возможностей языка, значительного эффекта можно добиться за счёт применения более эффективного алгоритма. Здесь у меня тоже есть над чем поработать. =)

пятница, 15 февраля 2008 г.

Проблемы с производительностью

В проекте, над которым я сейчас работаю, достаточно активно используются файлы в xml-подобном формате. И я решил написать для него парсер на Ruby. Сделать это оказалось достаточно просто, но вылезла другая проблема - проблема производительности. Файл в 650 строк на моём стариньком ноутбуке (500 МГц P3) парсится примерно 20 секунд. В Ruby есть очень полезаная библиотека profiler, позволяющая посмотреть сколько именно времени занимает каждая из частей программы. Причём для того, чтобы её применить не нужно ничего менять в своём коде, а достаточно только подключить профайлер. Так вот использование профайлера показало мне, что больше всего работы происходит внутри Array#each. Сейчас думаю, каким образом можно всё ускорить. Возможность сделать всё быстро доказывается наличием парсера rexml, полностью написаного на Ruby.

пятница, 8 февраля 2008 г.

Ещё одна книжка.

Предыдущую книгу я осилил почти неделю назад. Теперь взялся за следующую - Everyday Scripting with Ruby: for Teams, Testers, and You by Brian Marick. Эта книга также из той же серии, что и Programming Ruby. Здесь рассмотрено несколько практических примеров использования Ruby для всяческой автоматизации работы. Например инвентаризация файла или подсчёт количества изменений в SVN.

понедельник, 21 января 2008 г.

Книжка по Ruby

Нашёл и скачал в интернете неплохую книгу по Ruby - Programming Ruby. The Pragmatic Programmer's by Guide. David Thomas Andrew Hunt. Это книга тех же авторов, что и книги под названием "Программист-прагматик. Путь от подмастерья к мастеру", которую я читал ранее. Несмотря на то, что эта книга на английском, читается достаточно легко, чтобы я не бросил это занятие =).
Книга состоит из четырёх основных частей.

  1. Facets of Ruby. В этой части рассмотрены основные особенности Ruby и его отличия от других языков.
  2. Ruby in Its Setting. Здесь рассмотрено каким образом Ruby взаимодействует со своим окружением.
  3. Ruby Crystallized. Эта часть содержит в себе более продвинутый материал, относящийся к "сложным" частям языка.
  4. Ruby Library Reference. Описание встроенных классов и функций языка.

четверг, 17 января 2008 г.

Реальное применение

Вчера на работе понадобилось преобразовать файл из SVG-формата, в наш собственный. И для этого я решил написать скрипт. Вначале попробовал это сделать на Tcl, но у него таки несколько грамоздкий синтаксис, когда нужно заниматься поиском подстрок и тому подобными вещами(допускаю, что я просто недостаточно хорошо разобрался). Поэтому я использовал Ruby. Здесь проблем вообще не возникло. Я использовал то, что уже делал раньше и всё легко получилось. Так что похоже это и есть первый случай реального применения мной Ruby.

вторник, 15 января 2008 г.

Странная находка

Неожиданно обнаружил, что в составе Ruby присутствует библиотека tcltk, позволяющая использовать интерпритатор Tcl в Ruby-программе. Никак не могу придумать зачем это может понадобиться...