Текстовый редактор под Android
Выходные провёл с пользой - сделал ещё один простейший текстовый редактор, на этот раз под Андроид. Конечно, уже существует огромное множество готовых редакторов, но мне захотелось создать свой, ведь лучший способ научиться что-либо делать — делать самому. Собственно, идея сделать текстовый редактор появилась после того как я снёс с телефона Ted - работает весьма странно, иногда ни с того ни с сего портит кодировку файла а при сохранении постоянно спрашивает имя сохраняемого файла - это меня сильно достало, ведь сохраняюсь я постоянно, хотя, в целом ted — не плохой редактор.
Вообще, у меня полно задумок относительно того, что можно создать на этой платформе, вот, первый блин уже появился, надеюсь, что появятся и другие.
Большое спасибо Александру Понамарёву за классный диалог выбора файлов, без него у меня бы ушло гораздо больше времени.
Ссылка на apk файл.
PCRE поддерживает Posix литералы
Я уже писал, что нужно сделать, чтобы заменить в коде Posix регулярные выражения, которые в PHP 5.3 стали deprecated, на Perl совместимые. Оказывается Rerl совместимые регулярные выражения поддерживают литералы используемые в Posix такие как [[:allnum:]], [[:space:]] и т.д. В одном месте чужёго кода заметил это, и вот дошли руки проверить на практике: конструкция вида preg_match('/[[:space:]]/','df d') работает идентично конструкции вида preg_match('/\s/','df d') т.е. совсем не нужно при замене ereg на preg_match заменять еще и литералы, достаточно добавить слева и справа слеши "/". Кстати кроме слешей можно использовать любой другой символ, например "#" это полезно когда в регулярном выражении уже есть слеши - чтобы их не экранировать и не ухудшать читаемость кода.
Сравнение различных методов вызова функций в PHP
Вызов статических методов классов — прекрасная альтернатива обычным функциям - и класс создавать не нужно и принципы объектно-ориентированного программирования не нарушаются. Однако, в реализации статических методов в PHP есть несколько проблем - статические методы не всегда корректно наследуются, поэтому, чтобы нивелировать неудобства статических методов в PHP часто используют синглетоны - обертывают денимические методы статическими обертками.
Однако, создание синглетона операция довольно ресурсоёмкая — проверить создан ли экземпляр класса, создать экземпляр класса если он не создан, вызвать на нём нужный метод. Насколько это сказывается на бытродействии я и решил сегодня проверить.
Для оценки скорости доступа к методам синглетона я сделал небольшой скрипт. Скрипт генерирует тестовые последовательности вызовов функций в различных вариантах - и сравнивает время вызовов этих последовательностей.
Вот исходный код скрипта.
Результат работы скрипта представлен в таблице ниже:
generation_time | 11.7576429844 |
php_version | 5.3.2-1ubuntu4.9 |
Case | try 1 | try 2 | try 3 | try 4 | middle |
---|---|---|---|---|---|
Same plain function called 10000 times | 0.0166 | 0.0187 | 0.0183 | 0.0135 | 0.0168 |
Different plain functions called 10000 times | 0.0163 | 0.0221 | 0.018 | 0.0163 | 0.0182 |
Same static method 10000 times | 0.0193 | 0.0265 | 0.0206 | 0.0194 | 0.0214 |
Different static methods called 10000 times | 0.0221 | 0.0283 | 0.0229 | 0.0229 | 0.024 |
Static methods of different classes called 10000 times | 0.0236 | 0.0279 | 0.0251 | 0.0242 | 0.0252 |
Same dynamic method called 10000 times | 0.0166 | 0.0193 | 0.0169 | 0.0169 | 0.0174 |
Different class methods called 10000 times | 0.02 | 0.02 | 0.0202 | 0.02 | 0.02 |
Singleton method called 10000 times | 0.0403 | 0.0446 | 0.0409 | 0.041 | 0.0417 |
Different singletons called 10000 times | 0.0562 | 0.0631 | 0.0548 | 0.0572 | 0.0578 |
В тестовом скрипте, я сравнил обычные PHP функции, статические методы класса, обычные методы и методы синглетона.
Результаты тестирования показали, что вызов методов синглетона, примерно в два - четыре раза медленнее, чем вызов обычных методов, что, в принципе, меня порадовало — я ожидал, что будет хуже.
При этом выяснилось несколько дополнительных вещей: cтатические вызовы функций объявленных без модификатора "static" примерно в два раза медленнее, чем с ним, cтатические методы немного медленнее, чем динамические.
Так что, в принципе, синглетоны вполне можно использовать, особенно в случаях, когда быстродействие не сильно критично.
Странный глюк в PHP
Не знаю, сталкивался ли кто или это мне повезло, но вчера поймал загадочный баг, похоже, что в движке PHP, хотя, пока до конца не уверен.
Предыстория такая - работаю над проектом, над которым потрудились индийские программисты. Сам проект сделан на движке Symphony - добротный такой движок, вполне приятный. В качестве библиотеки работы с базой данных используется Creole - тоже довольно приятная штука. В качестве ORM используется Propel — штука громоздкая, но тем не менее тоже весьма мощная и простая. Вообще Symphony показался мне весьма неплохим движком, весьма простым и удобным. Наверно, потому, что он почти один в один копирует Ruby on Rails - те же хелперы, тот же yml в конфигах, такой же подход к MVC - в общем очень похоже.
Так вот, доблестные индийские программисты, вместо того, чтобы использовать оснастку из Symphony навставляли везде mysql_connect и mysql_query. И все бы ничего, но mysql_connect у них вставляется ВЕЗДЕ перед mysql_query — в одном скрипте может быть создано несколько десятков соединений, а каждый mysql_query дополняется проверкой "or die(mysql_error())", поэтому любая ошибка в sql ведет к скоропостижной кончине всего скрипта.
Чтобы хоть как то исправить это безобразие я сначала удалил все mysql_connect. Затем, все mysql_query поиском и заменой заменил на собственную функцию, использующую оснастку creole, поместил её в глобально видимый класс myTools::query():
static function query($sql){ $connection = Propel::getConnection(); $r = $connection->executeQuery($sql); return $r->getResource(); }
Странное дело код ведь тривиальный, но ресурс возвращаемый этой функцией оказался невалидным! Причем внутри функции ресурс еще остаётся рабочим а возвращённый во вне оказывается сломанным. Тот же код ВНЕ функции идеально работает, но как только выношу его в функцию — перестаёт работать.
Что это — глюк самого PHP или глюк Simphony я так и не понял, пришлось немного модифицировать класс MySQLConnection и добавить туда метод возвращающий MySQL ресурс непосредственно, минуя всякие PHP обёртки, но осадочек все же остался...