Пара интересных статей:
Musings on Data Oriented Design
Pitfalls of Object Oriented Programming (GCAP)
Суть вопроса, который поднимают авторы, такова -- за последние 30 лет развития IT скорость выполнения команд процессором выросла почти в 50000 раз, но время ответа памяти на запрос (memory latency) уменьшилось всего лишь раз в 10. В итоге мы получаем, что "стоимость" запроса к памяти (в циклах процессора) выросла примерно в 400 раз.
При этом современные компиляторы очень хорошо умеют работать с кодом -- фактически, машинный код, получаемый на выходе из компилятора может вообще не иметь ничего общего, с тем, что изначально было написано человеком -- кроме того, что делает то же самое. Но компиляторы очень мало что делают с данными -- размещение данных в памяти (data layout) генерируемое компилятором фактически очень мало отличается от того, что задекларировал программист в коде (разве что компилятор добавит туда от себя что-то -- vtable например, да выровняет по границам машинных слов). Хотя при современном состоянии дел с memory latency было бы гораздо выгоднее оптимизировать расположение данных под выполняемые задачи.
В частности, объектный подход, предлагающий группировать данные, относящиеся к одному объекту вместе, часто сильно уменьшает эффективность программы за счет того, что данные, нужные конкретному алгоритму, оказываются разбросанными по памяти. Итог - большое количество кэш-промахов, загрязнение кэша реально не нужными сейчас данными, большое количество простоев процессора в ожидании данных из основной памяти.
Вместо этого предлагается программисту (пока компиляторы не научились) продумывать размещение данных в памяти исходя из того, как они будут обрабатываться. В частности, в презентации (pdf) Том Албрехт показывает, как им удалось в 3-4 раза ускорить обновление-прорисовку дерева объектов сцены (scene tree) за счет изменения компоновки данных (там, правда, еще про предсказание ветвлений упомянуто)
25 февраля 2010 г.
15 февраля 2010 г.
JCaptcha
Разбирался на прошлой неделе с JCaptcha. Хорошая библиотека, но документация -- отвратная. Огромный разрыв между beginners guide и реальным использованием никак не покрыт. То есть начинаешь читать 5 minutes integration -- все вроде просто. Шаг чуть дальше -- нигде кроме как в исходниках инфы не найдешь.
Последний раз так с MFC мучался в дремучих 90-х. Думал уже, в мире джава таких проектов нет...
Вот, для примера, "переведенный" мною с языка spring-configuration на java код инициализации службы генерации капч:
Последний раз так с MFC мучался в дремучих 90-х. Думал уже, в мире джава таких проектов нет...
Вот, для примера, "переведенный" мною с языка spring-configuration на java код инициализации службы генерации капч:
private static final ImageCaptchaService instance;// = new DefaultManageableImageCaptchaService(); private static final int FONT_SIZE_MIN = 25; private static final int FONT_SIZE_MAX = 29; private static final int HEIGHT = 40; private static final int WIDTH = 200; static { //Шрифт, которым будет написана капча. Размер не важен final Font font = new Font( "Times New Roman", Font.PLAIN, 12 ); //разные буквы разными шрифтами разного размера final FontGenerator fontGen = new RandomFontGenerator( FONT_SIZE_MIN, FONT_SIZE_MAX, new Font[]{ font } ); //...и разными цветами final ColorGenerator colorGen = new RandomListColorGenerator( new Color[]{ Color.RED, Color.GREEN, Color.BLUE, Color.BLACK } ); //однотонный белый фон-подложка. здесь, по-сути, задается размер капчи final BackgroundGenerator bgGen = new UniColorBackgroundGenerator( WIDTH, HEIGHT, Color.WHITE ); //вырезаем слова от 6 до 9 букв final TextPaster textPaster = new RandomTextPaster( 6, 9, colorGen ); //список слов можно задать final FileDictionary dict = new FileDictionary( "toddlist" ); final WordGenerator wordGen = new DictionaryWordGenerator( dict ); //final WordGenerator wordGen = new ComposeDictionaryWordGenerator( dict ); final ComposedWordToImage wordToImage = new ComposedWordToImage( fontGen, bgGen, textPaster ); final CaptchaFactory factory = new GimpyFactory( wordGen, wordToImage ); final GenericCaptchaEngine engine = new GenericCaptchaEngine( new CaptchaFactory[]{ factory } ); instance = new GenericManageableCaptchaService( engine, 300, 500000, 1 ); }
12 февраля 2010 г.
JavaMail + SSL
Продолжение разбирательств. Краткий итог: итак, самый простой и надежный метод работы с SSL -- использовать
Все остальные настройки как в обычном smtp (только порт обычно 465 вместо 25). Работает с gmail -- проверено
Подробное описание:
Вариант с
не работает. Точнее, не совсем работает -- не так, как ожидается. Раскопки в исходниках JavaMail (благо, они доступны) показывают, что свойство
В числе прочего это означает, что если вы вместе с mail.transport.protocol = smtps укажете, как описано в документации, свойства типа mail.smpts.host -- они будут проигнорированы (использоваться будут свойства типа mail.smtp.host) и JavaMail будет ломиться на localhost (который используется в качестве адреса smtp сервера по-умолчанию).
System.setProperty("mail.smtp.ssl.enable","true");
Все остальные настройки как в обычном smtp (только порт обычно 465 вместо 25). Работает с gmail -- проверено
Подробное описание:
Вариант с
System.setProperty("mail.transport.protocol", "smtps")
не работает. Точнее, не совсем работает -- не так, как ожидается. Раскопки в исходниках JavaMail (благо, они доступны) показывают, что свойство
mail.transport.protocol
используется только методом Session.getTransport()
(который без аргументов). Но самой библиотекой этот метод не используется -- предполагается, что его вызывает клиентский код явно. Если вы отправляете почту через явно создаваемый транспорт, и получаете его через session.getTransport()
-- свойство mail.transport.protocol
будем иметь эффект. Если же вы, как я, отправляете почту через статический метод Transport.send()
, то внутри него библиотека ищет подходящий транспорт через вызовом getTransport(Address), что отсылает нас к свойству mail.transport.protocol.rfc822
(rfc822 -- такой "тип адреса" у адреса электронной почты). Если хочется переопределить транспорт для такого типа адресов на smpts -- надо писать System.setProperty("mail.transport.protocol.rfc822", "smtps");, либо использовать
session.setProtocolForAddress("rfc822", "smpts")
. Если просто написать mail.transport.protocol = smtps, то Transport.send() это указание проигнорирует. В числе прочего это означает, что если вы вместе с mail.transport.protocol = smtps укажете, как описано в документации, свойства типа mail.smpts.host -- они будут проигнорированы (использоваться будут свойства типа mail.smtp.host) и JavaMail будет ломиться на localhost (который используется в качестве адреса smtp сервера по-умолчанию).
JavaMail + SSL
Намучался искать нормальный (авторитетный) источник информации по отправке secure mail с помощью JavaMail. Secure -- это который через SSL и порт 465 (обычно).
В итоге нашел описание на самом java.sun.com (ссылка в заголовке).
Если я их правильно понял, есть 3 основных варианта (для самой свежей версии JavaMail -- 1.4.3)
Первый вариант просто указать системное свойство mail.smtp.ssl.enable=true. Провайдер вроде как должен сам понять, если имеет дело с секьюрным сервером.
Второй вариант -- последней версии можно использовать имя протокола smtps (pops, imaps) -- и, соответственно, все свойства задавать в виде mail.smtps.host, mail.smtps.port, etc.
Последний, самый старый вариант -- инсталлировать SSLSocketFactory через системное свойство mail.smtp.ssl.socketFactory.class
И еще гмайл и похожие сервера требуют установки свойства mail.smtp.starttls.enable=true.
В общем, JavaMail как обычно напоминает шаманские пляски.
В итоге нашел описание на самом java.sun.com (ссылка в заголовке).
Если я их правильно понял, есть 3 основных варианта (для самой свежей версии JavaMail -- 1.4.3)
Первый вариант просто указать системное свойство mail.smtp.ssl.enable=true. Провайдер вроде как должен сам понять, если имеет дело с секьюрным сервером.
Второй вариант -- последней версии можно использовать имя протокола smtps (pops, imaps) -- и, соответственно, все свойства задавать в виде mail.smtps.host, mail.smtps.port, etc.
Последний, самый старый вариант -- инсталлировать SSLSocketFactory через системное свойство mail.smtp.ssl.socketFactory.class
И еще гмайл и похожие сервера требуют установки свойства mail.smtp.starttls.enable=true.
В общем, JavaMail как обычно напоминает шаманские пляски.
5 февраля 2010 г.
String.trim()
Удивительно, но String.trim() не отбрасывает символ неразрываемого пробела 0x00A0. Я был просто поражен -- и нет даже никакой опции, как это убрать.
Более того, \s в регулярках тоже не считает 0x00A0 пробельным символом! Пришлось извращаться в духе [\s\u00A0]
Более того, \s в регулярках тоже не считает 0x00A0 пробельным символом! Пришлось извращаться в духе [\s\u00A0]
3 февраля 2010 г.
Gallery of Processor Cache Effects
Блог разработчика из Микрософт Игоря Островского. Влияние кэша процессора на производительность
Подписаться на:
Сообщения (Atom)