No public Twitter messages.


Этот блог устарел и, скорее всего, больше не будет обновляться. В ближайшем будущем он переедет сюда.
24 августа 2013 // Программинг

Производительность простых парсеров for fun

Сегодня в скайп-конфе попросили написать простой парсер удаляющий из большого файла все строки содержащие определённое ключевое слово. Быстро набросал достаточно грубый скрипт на Node.JS, который разбивал все 550мб на массив по переносу строки и проверял каждый элемент в цикле и изумился — файл в 530мб и ~1.7млн строк нода умудрилась преобразовать всего за 3 секунды.

Вот его код:

fs = require('fs')

fs.readFile 'data.txt', 'utf8', (err, data) ->
  file = data.split '\n'
  out = ''

  for string in file
    if string.search('/partner/') is -1
      out += string + '\n'

  fs.appendFile 'node_out.txt', out, (err) -> console.error err

Время исполнения — 2,9 секунды.

Стало интересно, как с такой задачкой справятся другие языки и я попросил друга написать такой же парсер на Perl, а затем подтянулись спецы по другим языкам появились и варианты на Python, Bash и Java. Примеры кода и время исполнения следуют дальше: Дальше →

теги: , , , , , ,

2 комментария.


29 марта 2010 // Программинг

DreamSpark и MSDN Academic Alliance для студентов

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

Часто приходится стоять на перепутье — скачать ломаную версию или выбрать бесплатную альтернативу. И каждый раз когда я выбираю второй вариант — это победа и я ей искренне радуюсь. Так было, например, при выборе ftp-клиента (сменил CuteFTP на FileZilla), офисного пакета (MS Office на OpenOffice).

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

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

MSDN Academic Alliance

По этой программе Microsoft подарил мне безвременные лицензии на профессиональные редакции Windows 7 и Visual Studio 2008. Помимо них по программе доступен просто необъятный список продуктов, включая

  • Windows Server 2008 R2,
  • Microsoft SQL Server 2008 (различных редакций),
  • Visual Studio 2008 (различных редакций),
  • Microsoft Robotics Developer Studio 2008 R2,
  • Microsoft CCR and DSS Toolkit 2008 R2,
  • XNA Game Studio 3,
  • Microsoft Surface SDK,
  • Access 2007,
  • InfoPath 2007,
  • OneNote 2007,
  • Project 2007,
  • Office SharePoint Server 2007

Да, MS Office тут не дают :)

Ищите у себя в ВУЗе объявления и спрашивайте у преподавателей что они знают об этой программе. Вся информация здесь.

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

Microsoft DreamSpark

Если честно, я сам не очень понимаю в чём эта программа отлична от msdnaa, однако здесь требуется только скан собственного студака (правда почему-то максимальный размер скана который можно им отправить — что-то в районе 50кбайт).

По этой программе можно получить тоже самое что и в msdnaa, однако помимо этого есть ещё и Expression Studio 3, Windows Embedded CE 6.0, Visual Studio 2010 Ultimate Beta 2, Microsoft Virtual PC и всяческие утилиты для разработки под Windows Phone.

Вся информация о программе здесь.

теги: , , ,

2 комментария.


26 июля 2009 // Программинг

Статистика сайта в Jabber

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

Ничего особо сложного в решении поставленной задачи нету, но тем не менее и написать обещал, и в твиттере уже есть как минимум 1 человек которому интересно, да и когда объясняешь много нового сам узнаёшь.

Нам необходимо написать 2 основных части. Первая — определение поисковика и запроса, вторая — отправка в джаббер. Язык у нас, естественно PHP.

Часть 1. Обработка суперглобального массива $_SERVER[‘HTTP_REFERER’]

Вся информация о поисковике и запросе хранится в суперглобальной переменной $_SERVER[‘HTTP_REFERER’]. При переходе с поискового сервиса выглядит примерно так: http://yandex.ru/yandsearch?text=%D0%BE%D0%B7%D0%B8%D0%BE&stpar2=%2Fh1%2Ftm8%2Fs1&stpar4=%2Fs1&stpar1=%2Fu0.

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

// кладём суперглобальную переменную в обычную, чтоб удобней работать было
$url = $_SERVER['HTTP_REFERER'];
// parse_url – разбиваем запрос на составляющие и отправляем в массив $complete
// urldecode – декодируем символы «%D0%BE%D0%B7%» в человеко-разумный вид
// trim – чистим содержимое от лишних пробелов и прочей пакости
$complete = parse_url(urldecode(trim($url)));
/* после всего колдовства массив $complete выглядит у нас примерно так:

Array
(
    [scheme] => http
    [host] => yandex.ru
    [path] => /yandsearch
    [query] => text=озио&stpar2=/h1/tm8/s1&stpar4=/s1&stpar1=/u0
)

*/
// выполняем остальной код только при наличии элемента query
if ($complete['query'] != '') {

parse_str($complete['query'], $output);

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

Теперь когда мы имеем разложенный по полочкам URL в массиве $complete всё значительно упрощается. Ну и для удобства мы точно также раскладываем по элементам содержимое элемента query, что бы иметь сам поисковый запрос отдельной переменной. А после уже начинаем проверку на поисковик.

Ну и после того как мы отпарсили элемент $complete[‘query’] мы имеем свой элемент массива с ключевой фразой. В зависимости от поисковика элемент имеет своё название, например на Яндексе ключевая фраза передаётся в переменной text, значит и элемент массива у нас называется $output[‘text’].

// функция eregi ищет в переменной $url слово 'yandex', если есть, то исполняется if
if (eregi('yandex', $url)) {

echo 'Вы пришли с Яндекса по запросу '.$output['text'];

}

Точно таким же образом с помощью elseif проверяем на причастность запроса к остальным поисковикам. Кстати, тут встретил такую малюсенькую тонкость — помимо обычного поиска Яндекса есть ведь ещё и Яндекс.Блоги и Яндекс.Картинки и всякое такое. Что бы их отловить надо использовать if с условием eregi(‘blogs.yandex’, $url), что, впрочем, логично.

Часть 2. Отправка сообщений в мессенджер с помощью фрэймворка xmphp.

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

Выбор фрэймворка был очень прост. На сайте xmpp.org он оказался единственным, без проблем позволяющим отправлять сообщения, написав всего пару строчек кода. Хотя, конечно, с ним тоже пришлось повозиться.

Во-первых, он не захотел работать со специально зарегистрированным мной ботом на gmail, хотя судя по примерам со страницы проекта gmail — стандарт. В общем благо проблем с Jabber-серверами у нас нету и я зарегистрировал бота на jabber.ru.

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

Ну и в-третьих, скрипт отказывался работать с включённым SSL/TLS шифрованием.

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

include ‘XMPPHP/XMPP.php’;

$conn = new XMPPHP_XMPP('allports.jabber.ru', 443, 'логин', 'пароль', 'xmpphp', 'jabber.ru', $printlog=false, $loglevel=XMPPHP_Log::LEVEL_INFO);
try
{
	$conn->connect();
	$conn->use_encryption = false;
	$conn->processUntil('session_start');
	$conn->presence();
	$conn->message('mr_ozio@livejournal.com', $output[text]."\n---\nЯндекс\n$doc_url");
	$conn->disconnect();
} catch(XMPPHP_Exception $e) {
	die($e->getMessage());
}

Тут дальше есть несколько вариантов. Вполне логично было бы вынести отправление в отдельный класс, но я как обычно решил всё упростить (или усложнить, тут с какой стороны посмотреть) и добавил в проверку по каждому поисковику.

Вот и всё.

А вот так это сегодня смотрелось в моём Pidgin’е.

теги: , , , ,

1 комментарий.



  • twitter
  • rss
  • хабр
  • жежека
  • ластфм