Страницы

понедельник, 28 декабря 2009 г.

Из двух зол..

из двух зол...
Вот снова выборы...И меня посетило некое дежавю, дежавю от того,что
когда-то такое уже было.Ах да,это это было прошлые выборы,и
позапрошлые,и позапозапрошлые...


Когда я еще был студентом,у нас был предмет политология.
Преподователем был практикующий политолог,который работал непосредственно на всех выборах в нашей стране.В принципе этот человек ничего нового мне не рассказал, но он обратил внимание на те простые вещи , с помощью которых они манипулирют нами.Не могу сказать ,что и мной тоже,но для меня было открытием ,что все выложенные им простые вещи действительно работают.Но тема данной статьи не об этом.Главная тема в том,что основные игроки нашей политики раз за разом остаются при власти,переменно меняя друг друга. Думаю,что повторюсь ,и что ни для никого не секрет о идее кардинальной смены элиты, и я не знаю человека ,который ее не поддержует.Но парадокс в том, что нынешняя элита, обладая абсолютной властью в наших СМИ, похоже подвела всех к мысли о том,что не из кого выбирать ,кроме как из красного или синего лагеря. Не буду называть их имена,вы итак догадались о ком я говорю.И все рейтинги указывают
именно на это.То есть получается, что желая перемен, мы выбираем снова старое, как в той поговорке "все новое - это хорошо забытое старое".Мне кажется, что это пародокс.



Вернемся к тому моему преподавателю. На наше замечание,что всеравно все купленно в наше стране, он заметил , что мы сами их выбираем."Так а что толку ,если все кто вертится в политике - коррупционеры, какой смысл выбирать?" - возразили мы.Он нам объяснил почему.И как все гениально - та мысль была проста.Вспомним конституцию - "народ едиственный источник
власти в этой стране", да так получилось что идеалистов в политике мало - не те правила игры.А мы забыли про это главное положение нашей конституции.Мы пошли на поводу у рекламы,пропаганды,заказных статей и стали играть в правила игры ,которые предлагают те, кто находятся у власти.
Мы забыли ,что выборы - это наша игра простых людей.И что кроме красного и синего в нашей политике есть еще большое количество разнообразных коррупционеров других цветов.Есть много других политиков ,которые себя еще не успели окончательно дискредитировать.Зачем выбирать снова
старых лошадей,которые себя уже давным-давно дискредитировали,ведь можно выбрать новых,которые уже два раза задумаются перед тем ,как снова пойти по стопам предшественников,помня как их лишили власти.Ведь по сути сейчас два лагеря соревнуются у кого ,больше грешков. Такое впечатление,что все забыли,что за один такой грешок уже можно казнить.
Следующие задумаются уже три раза,еще следующие четыра раза будуть думать прежде, чем воровать...Это наша игра и в ней есть : коричневые,зеленые,белые , а не только красный и синий.

среда, 3 июня 2009 г.

Инструменты

Дык, там справа есть ссылка "Сравнения языков программирования", перейдя по ней можно подробно ознакомиться с характеристиками 72 языков программирования при реализации различнх алгоритмов. Вообщем довольно интересное чтиво. Меня лично интересовали Java,C++,C,Python,php и мой любимый perl. Perl почти по всем параметрам ,я б сказал значительно проигрывает своим прямым конкурентам ;(. А php оказывается круче python-а, но хуже python3- а, что не может не радовать. Вот...

Сюрприз номер 1:

А теперь для меня откровением стало,что результаты java, хоть и хуже Си,но одного порядка с ним,то есть результаты в пределах секунд,но не десятков секунд!!!

Сюрприз номер 2:

С++ рвет - СИ ,вот это для меня откровение ! Хоть пересматривай свои взгляды на жизнь!правда памяти Си потребляет все таки поменьше,но по времени проигрывает! ;(


p.s У меня осталось слабая надежда,что если поправить коды тестов, то результаты могут быть другие,но все же если вспомнить ,что к примеру perl и php синтаксисом похожи становится обидно .Тенденция заметная....




Результаты:

C GNU gcc measurements

Program & Logs Time secs Memory KB Size B N
binary-trees18.03227,900963 20
chameneos-redux12.295801663 6,000,000
fannkuch17.05568937 12
fasta5.293961221 25,000,000
k-nucleotideMake Error
1141 25,000,000
mandelbrot6.0328,032879 16,000
meteor-contest0.0003066 2,098
n-body20.854121429 50,000,000
pidigits3.761,000541 10,000
regex-dna32.17124,7081099 5,000,000
reverse-complement1.48125,192722 25,000,000
spectral-norm2.996721139 5,500
thread-ring168.364,548487 50,000,000

Java 6 -server measurements

Program & Logs Time secs Memory KB Size B N
binary-trees19.64269,744603 20
chameneos-redux14.7017,2361429 6,000,000
fannkuch20.1412,0921150 12
fasta8.3111,1081240 25,000,000
k-nucleotide25.81881,1401348 25,000,000
mandelbrot11.1047,604903 16,000
meteor-contest0.301365177 2,098
n-body23.8811,1161424 50,000,000
pidigits6.9313,748938 10,000
regex-dna15.46563,6881534 5,000,000
reverse-complement3.02472,144592 25,000,000
spectral-norm4.0711,168950 5,500
thread-ring16.7196,404432 50,000,000

Perl measurements

Program & Logs Time secs Memory KB Size B N
binary-trees1346.11643,496541 20
chameneos-redux No program


fannkuch4679.111,664348 12
fasta363.292,128934 25,000,000
k-nucleotide248.51709,264359 25,000,000
mandelbrot1464.31290,392550 16,000
meteor-contest No program


n-body1996.452,1361140 50,000,000
pidigits8.083,312385 10,000
regex-dna47.06561,380440 5,000,000
reverse-complement38.17418,388298 25,000,000
spectral-norm1907.112,584334 5,500
thread-ring498.31488,604489 50,000,000

PHP measurements

Program & Logs Time secs Memory KB Size B N
binary-trees498.731,199,7561089 20
chameneos-redux No program


fannkuch1245.4417,580745 12
fasta264.163,3961030 25,000,000
k-nucleotide144.96247,9001268 25,000,000
mandelbrot714.85111,076863 16,000
meteor-contest2886.7311,3242582 2,098
n-body1236.793,4121255 50,000,000
pidigits7.628,524537 10,000
regex-dna47.30219,512449 5,000,000
reverse-complement7.09444,444343 25,000,000
spectral-norm296.7616,6241193 5,500
thread-ring No program



Python measurements

Program & Logs Time secs Memory KB Size B N
binary-trees2289.65221,232365 20
chameneos-redux221.852,968869 6,000,000
fannkuch4281.932,752387 12
fasta234.222,800779 25,000,000
k-nucleotide552.68439,196475 25,000,000
mandelbrot786.5318,488425 16,000
meteor-contest12.823,3081198 2,098
n-body1391.072,7961027 50,000,000
pidigits7.425,256476 10,000
regex-dna29.25188,200342 5,000,000
reverse-complement7.63452,356288 25,000,000
spectral-norm1108.453,324378 5,500
thread-ring252.597,148287 50,000,000

Python 3 measurements

Program & Logs Time secs Memory KB Size B N
binary-trees701.80271,192433 20
chameneos-redux221.484,220866 6,000,000
fannkuch4631.704,048400 12
fasta321.664,068788 25,000,000
k-nucleotide711.29840,332487 25,000,000
mandelbrot2104.705,512777 16,000
meteor-contest11.054,4241311 2,098
n-body1568.274,0761026 50,000,000
pidigits36.594,688437 10,000
regex-dna32.15376,652349 5,000,000
reverse-complement30.951,079,408294 25,000,000
spectral-norm1404.044,536366 5,500
thread-ring269.878,452288 50,000,000

C++ GNU g++ measurements


Program & Logs Time secs Memory KB Size B N
binary-trees5.71177,152888 20
chameneos-redux4.741,0721845 6,000,000
fannkuch14.061,1161186 12
fasta6.217401266 25,000,000
k-nucleotide13.61134,6481418 25,000,000
mandelbrot6.3729,396858 16,000
meteor-contest0.0005051 2,098
n-body20.747641428 50,000,000
pidigits3.781,724650 10,000
regex-dna9.01264,0562225 5,000,000
reverse-complement1.18245,0521098 25,000,000
spectral-norm2.999961114 5,500
thread-ring151.404,896588 50,000,000

понедельник, 1 июня 2009 г.

Осторожно mysql!!!

Вот иногда бывает!!!Это сообщение типа заметки об mysql, чтоб всегда помнил и не забывал.Итак есть две таблицы

desc search_words;
+---------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+----------------+
| sw_id | int(11) | NO | PRI | NULL | auto_increment |
| sw_word | varchar(255) | YES | MUL | NULL | |
+---------+--------------+------+-----+---------+----------------+

и

desc search_words_articles_count;
+-----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+-------+
| swac_swid | int(11) | YES | | NULL | |
| swac_aid | int(11) | YES | | NULL | |


вроде все ясно swac_swid это sw_id, sw_word текстовое значение слова
далее вроде бы безобидный запрос - требуется найти количество вхождений конкретных слов в ресурсах ,которые указаны в search_words_articles_count :

SELECT swac_swid,count(*) FROM search_words_articles_count WHERE swac_swid IN (SELECT sw_id FROM search_words WHERE sw_word IN ('из','нам','столь','до')) GROUP BY swac_swid;

в таблицах search_words_articles_count,search_words примерно 22 млн и 66 тыс записей соответсвенно .
Результата предыдущего запроса я не дождался!!!!
За то :
mysql> SELECT * FROM search_words WHERE sw_word IN ('из','нам','столь','до');
+-------+------------+
| sw_id | sw_word |
+-------+------------+
| 2869 | столь |
| 1569 | до |
| 2671 | из |
| 2059 | нам |
+-------+------------+
4 rows in set (0.07 sec)
а потом запустив запрос :
mysql> SELECT swac_swid,count(*) FROM search_words_articles_count WHERE swac_swid IN (2869,1569,2671,2059) GROUP BY swac_swid;
+-----------+----------+
| swac_swid | count(*) |
+-----------+----------+
| 1569 | 27833 |
| 2059 | 16504 |
| 2671 | 73176 |
| 2869 | 7733 |
+-----------+----------+
4 rows in set (6.42 sec)

получил результат ,который и хотел!!!

четверг, 21 мая 2009 г.

программирование и математика

Итак много программистов после окончания вузов и уже во время учебы в вузах говорят , что высшая математика им ничего не дает и только отвлекает от нормальной работы... То есть от нормального программирование на полюбившемся им языке...
Сначала я сам так думал,но после мне так попался труд господина Кнута , который дал мне ответы на вопросы, которые меня интересовали....
По сути после практики в три года я не мог дать рамки универсального и фундаментального кода для конкретной задачи....Да вообще что делает код достаточным для решения конкретной задачи....Что вообще значит достаточным?По сути в понимании этих аспектов и лежит разница между кодером и программистом...
Вывод пришел сам собой, после вывода что язык программирования это только лишь инструмент и ничего больше,ни идея,ни модель,ни стиль,ни философия, а только лишь инструмент. При помощи этого инструмента мы реализуем математическую модель....
Модель может быть задана при помощи классического математического аппарата,или аналитического,или множеств...
А наша задача, чтоб алгоритм сделанный нами при помощи нашего любимого инструмента нес наименьшие потери сравнительно с идеальным вариантом ,написанным на бумаге, при помощи обычных формул...

четверг, 19 марта 2009 г.

IF или религия

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

Бзз это убивает наше время...Мы трудным путем идем к идеалу и в то же время от него отталкиваемся - потому что перманентного идеала не существует,или можно перефразировать так идеал вещь относительная...
Суть в том что количество операций процессора исчисляется миллиардами в секунду, а и по сравнениею с этим избавление от одного if и экономление
нескольких десятков операций не имеет значения....
Пример из повседневной жизни программиста - проверка введенных значений формы первые два варианта событий для ООП:
1) Придумываем глобальный класс ,потом для каждой формы наследуем от этого класса и работаем
2) для каждой формы написать процедуру проверки с несколькими своими if-ами

В первом варианте мы потратим время на придумывание подходящей архитектуры,а потом, недели через две, будем со скрипом вспоминать как натягивать конкретный пример.
Во-втором примере мы будем знать куда лезть ,чтоб быро все поправить.
В итоге в первом примере мы выиграем допустим 10 милисекунд( это дохрена вообще-то), но эти милисекунды спокойно схаваються к примеру при маршрутизации пакетов по сети. Даже при клиентском приложении пользователь не заметит разницы в 10 милисекунд. И нахера вы спрашивается мудохались....
Но допустим вам надо собрать статистику с 1000 записей....Разница понятна...Об это был предыдущий пост в этом блоге.

среда, 18 марта 2009 г.

Хеши и JavaScript

Короче задолбало все время вспоминать как делаються нормально хеши в JavaScript потому запишу здесь

var hash = new Object();
var anotherHash = {};

Создание и инициализация массива выглядит следующим образом:
var hash = {"element1": "value2",
"element2": "value2",
"testKey": "testValue"};

Получить значение хеша по ключу можно 2-мя способами: либо обратится как к элементу массива,
используя в качестве индекса ключ - hash['testKey'], либо как к свойству объекта - hash.testKey.

Аналогичным образом происходит и изменение хеша, в случае когда элемент
не существует, он будет создан:
hash['element1'] = 'question';
hash.element2 = 'baz';

hash['answer'] = '42';
hash.foo = 'bar';

Пройтись по всем элементам массива можно используя for:
for( var item in hash ) {
alert(hash[item]);
}

четверг, 5 марта 2009 г.

Оптимизация,Xs,Perl и нахера это все нужно

Вообще этот пост является продолжением темы про идеальные языки.

Грубо говоря то xs это язык описания клея(интерфейся), которым вы будете связывать свою подпрограмму на perl c подпрограммой на C. Если вчитываться в доку , то вы буквально найдете перевод предыдущего предложения на английском.
Доку можно почитать здесь perlxs вернее perldoc perlxs ;). Она довольно обширная и меня не покидала мысль иногда а нахрена столько всего.Но я мужественно дочитал все до конца,а потом не не обнаружил нормального примера... Не сказать что меня это сильно расстроило но все же,учитывая сколько всего было прочитано ,стоял вопрос с какого конца надо подобраться.
Бла.бла.бла я как человек ленивый в конце концов нашел то что мне надо...
Утилита h2xs это именно то, что по-моему требуется сначала. Это утилита напишит весь код xs за вас, да еще и может сама модуль сгенерить.А ее глюки вы уж простите подправите сами,прочитав таки perlxs.

Краткий экскурс по h2xs

Допустим надо сделать модуль Neural - для нейронных сетей и реализацию его написать на С.
Начнем

h2xs -Afn Neural


Создаст пустой модуль со всеми атрибутами порядочного модуля Perl : Makefile.PL,Neural.pm и т.д.
Далее копируем например Neural.h и Neural.c в папку модуля
и выполняем следующую команду

h2xs -Oxan Neural Neural.h

Ну модуль готов с файлом xs.Выполняем perl Makefile.PL, make, make install и юзаем.За остальными вопросами обращайтесь man h2xs

А тут реальное говно,пардон 'Пример из жизни'.

Реальный пример, который много времени портил мне жизнь. В проекте тонким местом были большие объемы простых текстовых данных, есно они брались из базы данных,есно они обрабатывались и форматировались. Обратите внимание на слово форматировались. Нормальной выборкой содержала допустим 2000 записей, и в них могло содержаться от 1 до 5 числовых полей. Потребовалось форматирование по разрядам всех чисел. То есть из '1000000' сделать '1 000 000'.

RegExp!
Первое, что приходит в голову. Потом грубые прикидки и идея regexp -а для 2000 записей это от 2000 до 10000 как то мне не понравилась хотя бы из-за расходов памяти...Написал тогда я первый вариант процедуры разбития на разряды.


sub format_float
{
my $f=shift;
$f=~/([\-])?(\d+)\.(\d{1,2})$|([\-])?(\d+)/;

my $d='';
my $mines='';

unless($3)
{
$f=$5;
$mines=$4;
}else
{
$mines=$1;
$d=".$3";
$f=$2;
}
my @ar=split(//,$f);
my $size=@ar;
my $i=0 ;
my $res;
my $j=0;
$res.="$d";
for($i=$size-1;$i>=0;$i--)
{
unless($j)
{
$res=$ar[$i].$res;
$j++;
}else
{
$res=' '.$res unless($j%3);
$res=$ar[$i].$res;
$j++;
}

}
return $mines.$res;
}

За это долго сам себя буду пинать ногами,но надо было что-то сделать,а сверху пинали требовали заняться другим и т.п. Когда все утихло ,я вернулся к этому куску.Меня дико не устраивало,что обработка выборки занимала для любимых 2000 от 1 до 1.5 секунд.Сделаем regexp к слову это вариант перлиста коммуниста

sub regexp_format_float
{
my $f=shift;
$f=normal_prec($f);

# $f=~s/(\d{1,3})(?=\d{3})/$1 /g;
$f=~s/(\d{1,3})(?=((\d{3})+)\D?)/$1 /g;
return $f;
}

Причем при тесте производительности чисто лишь процедур в среднем вариант c reg-exp-ом был раза в три быстрее первого.Фигасе но при реальном тестирование такого прироста не наблюдалось.Вот тут вспомним про С и XS. Напишем format_float.h , где определим

char * C_format_float(double);

и format_float.c


#include
#include
#include



char * C_format_float(double num)
{
char buffer[60];
char *str,*str1;
char * str_out;
int i,size,j,z,ext;
char tmp;

sprintf(buffer, "%f", num);

size=strlen(buffer);

str=strtok(buffer,".");

size=strlen(str);
ext=(int)size/3;
str_out = malloc(100);


j=0;//
size--;
z=1;//reverse index
for(i=size;i>=0;z++,i--)
{

tmp=str[i];
str_out[i-j+ext]=tmp;
if((z%3)==0)
{
j++;
tmp=' ';
str_out[i-j+ext]=tmp;
}


}
str_out[size+ext+1]='.';
//str_out[size+ext+2]='\0';
str=strtok(NULL,".");
if(str==NULL) return str_out;
str_out[size+ext+2]=str[0];
str_out[size+ext+3]=str[1];
str_out[size+ext+4]='\0';
//strcat(str_out, str);
return str_out;
}

Потом проведем операции из первого абзаца:

bash # h2xs -Afn Format
bash # cp /home_dir/xs/format_float.* /home_dir/Format/
bash # h2xs -Oxan Format format_float.h

Готово можно подключать...Далее могу сказать, что здесь я остановился в оптимизации данного куска кода. В данном случае я говорю о функции char * format_float(double num).Ибо написав скрипт , чтоб посмотреть разницу во времени для всех реализаций

#!/usr/bin/perl
use lib q(.);
use SiteCommon;#содержит процедуры формаирования на Perl
use Format;# C -реализация
use Benchmark qw(:all) ;

timethese(100000, {
'format_float without regexp' => sub { SiteCommon::format_float(1000000.00) },
'format_float on C' => sub { Format::C_format_float(1000000.00) },
'format_float with regexp' => sub { SiteCommon::regexp_format_float(1000000.00) },

});

timethese(100000, {
'format_float without regexp' => sub { SiteCommon::format_float(10000.00) },
'format_float on C' => sub { Format::C_format_float(10000.00) },
'format_float with regexp' => sub { SiteCommon::regexp_format_float(10000.00) },

});
timethese(100000, {
'format_float without regexp' => sub { SiteCommon::format_float(11.00) },
'format_float on C' => sub { Format::C_format_float(10.00) },
'format_float with regexp' => sub { SiteCommon::regexp_format_float(13.00) },

});

Получили примерно следующие результаты


Benchmark: timing 100000 iterations of format_float on C, format_float with regexp, format_float without regexp...
format_float on C: 1 wallclock secs ( 0.31 usr + 0.03 sys = 0.34 CPU) @ 294117.65/s (n=100000)
(warning: too few iterations for a reliable count)
format_float with regexp: 2 wallclock secs ( 2.12 usr + 0.09 sys = 2.21 CPU) @ 45248.87/s (n=100000)
format_float without regexp: 5 wallclock secs ( 5.58 usr + 0.10 sys = 5.68 CPU) @ 17605.63/s (n=100000)
Benchmark: timing 100000 iterations of format_float on C, format_float with regexp, format_float without regexp...
format_float on C: 0 wallclock secs ( 0.30 usr + 0.01 sys = 0.31 CPU) @ 322580.65/s (n=100000)
(warning: too few iterations for a reliable count)
format_float with regexp: 2 wallclock secs ( 1.84 usr + 0.08 sys = 1.92 CPU) @ 52083.33/s (n=100000)
format_float without regexp: 7 wallclock secs ( 4.81 usr + 0.18 sys = 4.99 CPU) @ 20040.08/s (n=100000)
Benchmark: timing 100000 iterations of format_float on C, format_float with regexp, format_float without regexp...
format_float on C: 0 wallclock secs ( 0.27 usr + 0.01 sys = 0.28 CPU) @ 357142.86/s (n=100000)
(warning: too few iterations for a reliable count)
format_float with regexp: 2 wallclock secs ( 0.70 usr + 0.00 sys = 0.70 CPU) @ 142857.14/s (n=100000)
format_float without regexp: 4 wallclock secs ( 3.76 usr + 0.11 sys = 3.87 CPU) @ 25839.79/s (n=100000)

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

среда, 4 марта 2009 г.

Идеальный язык и с чем его едят

Ну в нынешнем разнообразии языков программирования высокого уровня можно потеряться)) ведь неправда ли)) А красноглазики с пеной у рта доказывают , что именно их язык лучше... Другие красноглазики спорят, что лучше ООП или ПОП(процедурно ориентированное )... Во все этом я совершенно потерялся,потерялся я главным образом потому,что один мой товарищ вместе, с которым мы начинали писать и осваивать этот неоднозначный мир,сказал,что глубоко имел ввиду Perl, что он не прочь перейти на java-у,ruby или даже python. Это случилось полгода назад...И сидя с больной ногой дома , я снова вернулся к этой теме.
Я пишу на perl , потому что мне это удобно,люди пишут на php -потому что это удобно,люди пишут на C , потому что это удобно....Знаете почему им удобно, потому что язык программирования - это инструмент ,который придумывали для решения каких-то целей.А хороший инструмент должен быть удобен, на то он и инструмент.И продолжу мысль ,и у каждого инструмента есть свое применение - ведь не будет вы в самом деле забивать гвозди отверткой( конечно можно и сам так делал,но согласитесь неудобно).
Потому мой perl еще долго жить в моем сердце. Но мы ж говорим про идеальные языки , а инструмент не может быть идеальным по своему определению, если его попытаться сделать идельным он станет настолько громоздким и не удобным, что перестанет быть идеальным,так как им тупо херево пользвоаться.
Тогда а что нам делать,когда вот есть проект для его написания используется какой-то конкретный инструмент.Но с развитием проекта его задачи расширились, и используемый инструмент перестал отвечать части задачь проекта...Тут начинается изобретение велосипеда - плохой вариант, или воспользоваться вторым вариантом использовать другой инструмент.
Благо все языки поддержуют возможность написания расширений на других языках. Для моего горячо любимого Perl есть такая штука как xs ;), для php есть всякие streams,java вообще имеет чуть ли не встроенную поддержку использования кода на C. Так вот как слесарь ходит с чемоданом отверток, так и в программировании есть чемодан языков уместное использование кадого из них и будет давать нам результат близкий к идеальному)