Команда противника долго оттягивала свой конец...
(со слов телекомментатора)
Заниматься подготовкой да стратегией - дело приятное, но пора вспомнить и про саму программу.
Поехали!
Достаю из широких штанин, то есть из архива свои исходники, запускаю дельфи. Перво-наперво нужно убедиться, что все компилируется и вспомнить, что тут к чему.
В проект включены три файла, которые используют шесть модулей (указаны в uses). Для компиляции потребовалось отыскать в архивах еще три модуля. После компиляции в выходном каталоге обнаружил 36 dcu-файлов. 8-)
Для такой простой программы - многовато будет.
Размер выходного файла - 422 кБ.
Будем разбираться.
Во-первых, вижу семь dcu-шек от RxLib. Не могу припомнить, чтобы они тут использовались. Наверно их потребовал какой-то плохо разделенный используемый модуль.
Насколько я помню, с RxLib возникли какие-то проблемы при переходе на шестые дельфи - авторы отказались от дальнейшего развития и поддержки и отдали(продали?) все права какой-то непонятной зарубежной фирме. Я находил несколько версий RxLib для delphi 6 от разных авторов-доработчиков. Какую из них лучше будет взять - совершенно непонятно.
Потом вижу десять dcu от html-парсера.
Надо посмотреть на этот парсер поближе.
Первые грабли: оказывается, парсер бесплатный только для некоммерческого использования. В документации сказано:
"If you intend to use it commercially, please contact me ..." Значит, будем заменять его чем-то другим.
К счастью, всего месяц назад я озаботился похожей проблемой - нужно было конвертировать некоторое (большое) количество html, засоренных всякой всячиной в txt.
Те пять или семь утилит-конвертеров, которые оказались под рукой, меня не удовлетворили и кончилось тем что я написал свой. Как всегда бывает в таких случаях, на следующий же день попалась замечательная бесплатная программа ClearTxt, в которой все что надо уже реализовано и теперь я пользуюсь ей.
Вернемся к парсеру.
Чтобы найти нужное место, пришлось залезть глубоко внутрь используемых модулей, туда, куда уже больше года как не ступала рука программиста.
В том модуле, где он подключался, я оставил достаточно много комментариев, чтобы быстро вспомнить что к чему.
Теперь нужно подключить свой конвертор на место старого. Мне он нужен только чтобы вытаскивать весь текст из html.
Разбираясь в старом коде понял, что значительно проще вытащить только то, что я реально использую, куда-нибудь в отдельный модуль, чем каждый раз бегать по нескольким старым.
Переписал в новый модуль нужные объекты и куски кода.
Подключил новый конвертер.
По ходу дела обнаружил, что еще один модуль из uses уже давно не использую. Закомментировал.
Компилирую. В результате осталось только 9 dcu, а размер программы уменьшился до 376 К.
Полученному чуду присвоен номер 1.1.03
Ура? Нет, еще не ура. Теперь нужно убедиться, что программа по-прежнему работает, а заодно и сравнить скорость со старой версией.
Из того, что было под рукой, взял html-файл размером 1435117 байт (1402 Кб).
Запускаю сначала старую, потом новую версию. В списке результатов - 13657 терминов.
Увы. Оказывается, что мой код работает примерно в 10 раз медленнее! А я-то надеялся... :-(
В любом случае, использовать старый вариант нельзя - из-за авторских прав. То есть, надо либо разобраться - что у меня не так, либо найти другой способ - обязательно должны быть какие-то фриварные компоненты для разбора html.
Конечно, интересней довести до ума свой код.
После несложных преобразований программа лишилась еще нескольких кусков кода, размер exe-шника уменьшился на 1кб, а скорость возросла. Работает по-прежнему медленнее, но теперь всего в два раза.
На этом, пожалуй, можно пока и остановиться.
Но аппетит приходит во время еды и ...
... и выходной файл уменьшается еще на полтора килобайта, ну а скорость ... остается той же ;(
На следующий день до меня наконец дошло, что чем улучшать то что есть, проще написать отдельный конвертер html-txt, без всех наворотов, которые были уже предусмотрены - мне ведь не нужно сохранять ссылки, обрабатывать разные теги форматирования - учитывать выделение текста, извлекать текст из описание alt к картинкам и тому подобное.
Все, что мне нужно сделать -
вырезать и удалить все, что находится между парами символов "<" и ">", между парами "<!--" и "-->", и между парными тегами script, и style.
Сказано - сделано.
Испытания новой компиляции дали еще более странный результат - в 15 раз медленнее исходного... :-((
Начали подкрадываться мысли - оставить все как есть. Никого ведь не интересует скорость выполнения,
главное, чтобы программа работала и выполняла свои функции
и запускать ее будут на компьютерах в 5-10 раз быстрее моего и так далее и тому подобное.
Но все-таки совершенно не понятно - почему набор таких простых операций выполняется так долго!
Через пол-часа вернувшись к компьютеру "свежим взглядом" нахожу несколько ... скажем так - не слишком умных вещей.
Исправляем. Запускаем ...
Наконец-то!!! Ура!
Программа работает на 30% быстрее старого варианта (с чужим парсером) - и это при том, что основную часть программы я еще даже не трогал.
Размер файла - 373.76 кб, т.е. еще на пару кб меньше.
Итак, первая поставленная задача решена - чужой и несвободный html-парсер заменен своим.
Полученному результату присвоен номер 1.1.04. В упакованном виде он оказался на 10% короче версии 1.1.02
Надо двигаться дальше.
А если вдруг окажется, что и какие-то другие не мои модули - не бесплатные? Будем проверять.
Для обработки строк я использовал библиотеку
QStrings 5.02.267 (public release), Russian version, Copyright (C) 2000, Andrew N. Driazgov, Portions (C) 2000, Sergey G. Shcherbakov - мои им благодарности.
Оказалось, что есть более свежая версия QStrings 6.06, где сказано:
Вы можете использовать данный модуль в любых своих проектах (в том числе коммерческих) без всяких ограничений. ... Модуль QStrings распространяется на условиях freeware.
unit htmtotxt;
var fhtml:string;
procedure ConvertIt;
...
implementation
uses Classes, QStrings;
procedure ConvertIt;
var curr,curr2:integer;
VStrings:TStringList;
procedure delit(beginstr,endstr:string);
var l2:integer;
begin
l2:=length(endstr);
curr:=Q_PosText(beginstr,fhtml);
while (curr<>0) do
begin
curr2:=Q_PosText(endstr,fhtml,curr);
Q_Delete (fhtml,curr,curr2-curr+l2);
curr:=Q_PosText(beginstr,fhtml,curr);
end;
end;
begin
...
Q_SpaceCompressInPlace(fhtml);
curr:= Q_PosText('</HEAD>',fhtml); //<HEAD> </HEAD>
Q_Delete(fhtml,1,curr+7);
curr:=Q_PosStr('<!--',fhtml); //<!-- "--" и потом ">"
while (curr<>0) do
begin
curr2:=Q_PosStr('--',fhtml,curr+3);
curr2:=Q_PosStr('>',fhtml, curr2);
Q_Delete(fhtml,curr,curr2-curr+1);
curr :=Q_PosStr('<!--',fhtml,curr);
end;
delit('<SCRIPT','</SCRIPT>'); // <SCRIPT </SCRIPT>
delit('<STYLE' ,'</STYLE>' ); // <STYLE </STYLE>
VStrings:=TStringList.Create; //delit('<','>'); // < >
curr :=Q_PosText('<',fhtml);
curr2:=0;
while (curr<>0) do
begin
VStrings.Add(Copy(fhtml,curr2+1, curr-curr2-1));
curr2:=Q_PosText('>',fhtml,curr );
curr :=Q_PosText('<',fhtml,curr2);
end;
fhtml:=VStrings.text+Copy(fhtml,curr2+1, length(fhtml)-curr2);
VStrings.Free;
begin
if Q_PosText(' ',fhtml) <>0 then fhtml:=Q_ReplaceStr(fhtml, ' ',' ');
if Q_PosText('<' ,fhtml) <>0 then fhtml:=Q_ReplaceStr(fhtml, '<' ,'<'); // < представляет знак <
if Q_PosText('>' ,fhtml) <>0 then fhtml:=Q_ReplaceStr(fhtml, '>' ,'>'); // > представляет знак >
if Q_PosText('&' ,fhtml) <>0 then fhtml:=Q_ReplaceStr(fhtml, '&' ,'&'); // & представляет символ &
if Q_PosText('"',fhtml) <>0 then fhtml:=Q_ReplaceStr(fhtml, '"','"'); // " представляет знак "
end;
...
end;
end.
Но это надо будет еще хорошенько оттестировать...
Хроника текущих событий
Решил немного уточнить свою установку "не тратить, а зарабатывать". Заказал два источника знаний. Получил их:
С. Баричев, А. Лысковский “3,5 дюйма, или Как продавать свои программы через Интернет”,
С. Жарков “Shareware: профессиональная разработка и продвижение программ”
Буду теперь читать, чужого ума набираться ;)
На сегодня все...
Ведущий проекта - Алексей.
Есть что сказать? пишите сюда: blackbox@mailru.com Все, что вы напишете, может быть использовано для вас в рассылке. Если вы против публикации своего письма, укажите тему письма "секретно" или "не публиковать".