Обнаружил, что в PHP функция unserialize может серьёзно задуматься, если целевой объект - большой массив. В причинах пока не разобрался.
ini_set('memory_limit', '512M');
$file = '/tmp/1';
$data = range(1,2000000);
echo "Test serialize\n";
$time0 = microtime(1);
file_put_contents($file, serialize($data));
$time1 = microtime(1);
unserialize(file_get_contents($file));
$time2 = microtime(1);
$timeset = $time1-$time0;
$timeget = $time2-$time1;
echo "Serialize set time $timeset get time $timeget\n";
echo "Test JSON\n";
$time0 = microtime(1);
file_put_contents($file, json_encode($data));
$time1 = microtime(1);
json_decode(file_get_contents($file), true);
$time2 = microtime(1);
$timeset = $time1-$time0;
$timeget = $time2-$time1;
echo "JSON set time $timeset get time $timeget\n";
Результат работы
Test serialize
Serialize set time 1.39576292038 get time 31.2712199688
Test JSON
JSON set time 0.270380973816 get time 1.33044695854
воскресенье, 12 сентября 2010 г.
среда, 4 августа 2010 г.
МТС: Как отключить рекламу в SMS
Компания МТС не перестаёт меня радовать. Оказывается через интернет помощник можно не только отключить все левые "бесплатные" услуги от оператора. Так можно ещё отказаться от получения рекламы. Узнал я об этом просто написав им в поддержку. Вот ответ.
Описание услуги есть на странице http://www.mts.ru/services/communication/sms/ (вкладка Запрет приема SMS)
Вобщем я приятно удивлён. Спасибо МТС!
Алексей, для отказа от SMS-рассылки Вы можете воспользоваться бесплатным сервисом "Интернет-Помощник". Предварительно установите, пожалуйста, пароль для доступа (от 4 до 7 цифр) к сервису, набрав с мобильного телефона комбинацию *111*25# клавиша вызова (запрос бесплатный). Для входа в "Интернет-Помощник" перейдите, пожалуйста, по ссылке https://ihelper.mts.ru/selfcare/logon.aspx, где Вам будет предложено ввести 10-значный номер телефона и пароль. Затем выберите, пожалуйста, подраздел "Тарифы, услуги и скидки", далее "Управление услугами"/"Подключить новые услуги". Добавьте услугу "Запрет приема информационных SMS и SMS/MMS с сайта МТС".
Описание услуги есть на странице http://www.mts.ru/services/communication/sms/ (вкладка Запрет приема SMS)
Вобщем я приятно удивлён. Спасибо МТС!
четверг, 1 июля 2010 г.
PHP socket_select - не подходит для написания сетевых приложений
UPD В первой редакции статьи я ошибочно писал про stream_select. Статья отредактирована подобающим образом.
Обнаружил очень забавное поведение у функции socket_select - она не возвращают информацию об изменениях, если в буфере чтения уже лежат какие-то данные. Получается просто зацикливание приложения на socket_select. Такого поведения в принципе легко достичь, если медленно обрабатывать большой пакет данных.
Алгоритм до безобразия прост.
Шаг 1. socket_select рапортует, что данные в буфере. Вычитываешь их и обрабатываешь.
Шаг 2. Вычитываешь и обрабатываешь предпоследний пакет данных. И пока ты его обрабатываешь в буфер приходит недостающий последний пакет.
Шаг 3. Ты вызываешь socket_select и ждёшь данные. Так как данные уже пришли, socket_select тебе об этом не говорит. Получается, что в буфере уже лежат нужные тебе данные, но не предоставляется никакого механизма узнать об этом. Потому ты будешь ждать ответа пока данные снова не придут в этот сокет. А они могут вообще не придти, если протокол последовательный.
С неблокирующими сокетами - та же проблема. Прежде чем передать сокеты в socket_select надо проверить все буферы чтения. А пока ты их проверяешь, данные могут придти и улечься в буфер чтения. Снова ты их потеряешь.
Выводы:
socket_select в общем случае не подходит для задачи написания сетевого приложения. В общем случае надо использовать работу с неблокирующими сокетами и перебор сокетов. Обнаружил, что недавно зарелизилась libevent для PHP надо будет попробовать инструмент в действии. В конце концов она работает не на селектах, а на epoll и kqueue.
UPD Для написания сетевого приложения можно использовать stream_select, она лишена указанного недостатка socket_select
PS. Спасибо Clanth
Обнаружил очень забавное поведение у функции socket_select - она не возвращают информацию об изменениях, если в буфере чтения уже лежат какие-то данные. Получается просто зацикливание приложения на socket_select. Такого поведения в принципе легко достичь, если медленно обрабатывать большой пакет данных.
Алгоритм до безобразия прост.
Шаг 1. socket_select рапортует, что данные в буфере. Вычитываешь их и обрабатываешь.
Шаг 2. Вычитываешь и обрабатываешь предпоследний пакет данных. И пока ты его обрабатываешь в буфер приходит недостающий последний пакет.
Шаг 3. Ты вызываешь socket_select и ждёшь данные. Так как данные уже пришли, socket_select тебе об этом не говорит. Получается, что в буфере уже лежат нужные тебе данные, но не предоставляется никакого механизма узнать об этом. Потому ты будешь ждать ответа пока данные снова не придут в этот сокет. А они могут вообще не придти, если протокол последовательный.
С неблокирующими сокетами - та же проблема. Прежде чем передать сокеты в socket_select надо проверить все буферы чтения. А пока ты их проверяешь, данные могут придти и улечься в буфер чтения. Снова ты их потеряешь.
Выводы:
socket_select в общем случае не подходит для задачи написания сетевого приложения. В общем случае надо использовать работу с неблокирующими сокетами и перебор сокетов. Обнаружил, что недавно зарелизилась libevent для PHP надо будет попробовать инструмент в действии. В конце концов она работает не на селектах, а на epoll и kqueue.
UPD Для написания сетевого приложения можно использовать stream_select, она лишена указанного недостатка socket_select
PS. Спасибо Clanth
четверг, 24 июня 2010 г.
readme задолбал. Начинаю борьбу
Написал скрипт для greasemonkey, который убивает onclick у всех ссылок и перекидывает на целевую страницу.
function gs_init(){
els = document.getElementsByTagName('a');
for(el in els){
els[el].onclick="";
}
if(document.getElementsByClassName('newstext')[0].childNodes[1].childNodes[0].href)
document.location = document.getElementsByClassName('newstext')[0].childNodes[1].childNodes[0].href;
}
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", gs_init, false);
}
function gs_init(){
els = document.getElementsByTagName('a');
for(el in els){
els[el].onclick="";
}
if(document.getElementsByClassName('newstext')[0].childNodes[1].childNodes[0].href)
document.location = document.getElementsByClassName('newstext')[0].childNodes[1].childNodes[0].href;
}
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", gs_init, false);
}
вторник, 22 июня 2010 г.
Поисковики
Несколько достаточно полезных поисковиков.
Поиск картинок по картинкам
http://www.tineye.com/ - находит картинки, похожие на заданную. Мне был полезен, когда надо было определить знаменитость по фотографии.
Поиск названия шрифта по картинке
http://new.myfonts.com/WhatTheFont/ - находит шрифт по хожий на шрифт с картинки. Однажды пришлось исправлять текст на картике, а подобрать похожий шрифт не получалось.
Поиск музыки по мелодии
http://www.midomi.com/ - находит музыкальное произведение по мелодии. Бывает такое, что в песне ни слова не разобрать, да и слышал ты её где-нибудь на рынке. Этот сервис поможет найти песню.
А вообще, я приятно удивлён, что поисковые технологии совсем не ограничиваются поиском по тексту. Увлекательная работа у людей, которые создают такие интересные инструменты.
Поиск картинок по картинкам
http://www.tineye.com/ - находит картинки, похожие на заданную. Мне был полезен, когда надо было определить знаменитость по фотографии.
Поиск названия шрифта по картинке
http://new.myfonts.com/WhatTheFont/ - находит шрифт по хожий на шрифт с картинки. Однажды пришлось исправлять текст на картике, а подобрать похожий шрифт не получалось.
Поиск музыки по мелодии
http://www.midomi.com/ - находит музыкальное произведение по мелодии. Бывает такое, что в песне ни слова не разобрать, да и слышал ты её где-нибудь на рынке. Этот сервис поможет найти песню.
А вообще, я приятно удивлён, что поисковые технологии совсем не ограничиваются поиском по тексту. Увлекательная работа у людей, которые создают такие интересные инструменты.
воскресенье, 20 июня 2010 г.
PHP abstract static function - о_0
<?php
abstract class A {
abstract static function f1();
static function f2(){
echo self::f1("\n");
}
}
class B extends A {
static function f1(){return 'test';}
}
B::f2();
Fatal error: Cannot call abstract method A::f1() in 1.php on line 6
abstract class A {
abstract static function f1();
static function f2(){
echo self::f1("\n");
}
}
class B extends A {
static function f1(){return 'test';}
}
B::f2();
Fatal error: Cannot call abstract method A::f1() in 1.php on line 6
среда, 16 июня 2010 г.
Определение фазы луны по дате на PHP
Потребовалось мне как-то определить время охоты на обортней. Вроде логично - полнолуние. Полез я разыскивать, что такое полнолуние и понял, что понятие "полнолуние" - весьма непродолжительное. Всего-то мгновение. Причем не обязательно в нашей половине планеты будет ночь. Сначала хотел ограничить ночь полнолуния - от заката до рассвета в дату полнолуния. И тут я наступил на ещё один камень, оказывается ночь - не одна дата, а (внезапно) две. Потому решил привязаться к менее дискретному понятию - фазам луны. Итог, ночь полнолуния, когда фаза луны между 14.5 и 15.5 от заката до рассвета. И вот собственно PHP код для определения фазы луны.
function get_moon_phase_normalize( $v ){
$v = $v - floor( $v );
if($v < 0) {
$v = $v + 1;
}
return $v;
}
function get_moon_phase($timestamp){
$date = date("Y-m-d", $timestamp);
list($Y, $M, $D) = explode('-', $date);
$YY = $Y - floor(0.0 + (12 - $M) / 10);
$MM = ($M + 9)%12;
$K1 = floor(365.25 * ($YY + 4712));
$K2 = floor(30.6 * $MM + 0.5);
$K3 = floor(floor(($YY / 100) + 49) * 0.75) - 38;
$JD = $K1 + $K2 + $D + 59;
if($JD > 2299160)
$JD = $JD - $K3;
$IP = get_moon_phase_normalize(($JD - 2451550.1) / 29.530588853);
$AG = $IP*29.53;
return $AG;
}
Алгоритм взят с http://blogs.msdn.com/b/rucoding4fun/archive/2009/09/07/arduino.aspx
function get_moon_phase_normalize( $v ){
$v = $v - floor( $v );
if($v < 0) {
$v = $v + 1;
}
return $v;
}
function get_moon_phase($timestamp){
$date = date("Y-m-d", $timestamp);
list($Y, $M, $D) = explode('-', $date);
$YY = $Y - floor(0.0 + (12 - $M) / 10);
$MM = ($M + 9)%12;
$K1 = floor(365.25 * ($YY + 4712));
$K2 = floor(30.6 * $MM + 0.5);
$K3 = floor(floor(($YY / 100) + 49) * 0.75) - 38;
$JD = $K1 + $K2 + $D + 59;
if($JD > 2299160)
$JD = $JD - $K3;
$IP = get_moon_phase_normalize(($JD - 2451550.1) / 29.530588853);
$AG = $IP*29.53;
return $AG;
}
Алгоритм взят с http://blogs.msdn.com/b/rucoding4fun/archive/2009/09/07/arduino.aspx
Подписаться на:
Сообщения (Atom)