Nov 28, 2007

Глупое сравнение производительности Ruby и Java

Нечего было делать среди ночи... вот чего учудил в ответ на: http://myskitch.com/yaroslavlazor/main.rb-20071127-210826.jpg Еще отличная ссылка по теме: http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=java&lang2=ruby Не удержался и решил провести еще несколько экспериментов. Прежде всего, правильнее всего будет вычислять время непосредственно в программе, для чего был добавлен соответствующий инструментальный код. Далее, мне стало интересно, как поведет себя в этой ситуации популярная библиотека "Commons Lang". Вот что получилось в результате: Пример кода 1:
 
    public static void main(String[] args) {
        final long t1 = System.currentTimeMillis();
        final int n = Integer.parseInt(args[0]);
        final StringBuilder b = new StringBuilder( n * TEXT.length());
        for (int i=0;i<n;i++) {
            b.append(TEXT);
        }
        System.out.println("Result:"+b.reverse().length());
        System.out.println("Time:"+(System.currentTimeMillis()-t1)/1000.0);
        
    }
Результат:
etf@etf-desktop:~/prog/JavaApplication1/dist$ time java -jar -Xmx512M -Xms512M JavaApplication1.jar 10000000
Result:50000000
Time:0.936

real    0m1.184s
user    0m0.844s
sys     0m0.208s
Пример кода 2:
    public static void main(String[] args) {
        final long t1 = System.currentTimeMillis();
        System.out.println("Result:"+StringUtils.reverse(StringUtils.repeat(TEXT, Integer.parseInt(args[0]))).length());
        System.out.println("Time:"+(System.currentTimeMillis()-t1)/1000.0);
        
    } 
Результат:
etf@etf-desktop:~/prog/JavaApplication1/dist$ time java -jar -Xmx512M -Xms512M JavaApplication1.jar 10000000
Result:50000000
Time:2.233

real    0m2.414s
user    0m1.888s
sys     0m0.400s
Пример кода 3 (Ruby):
  t1 = Time.now;
  puts "Result:" + ("test " * ARGV[0].to_i).reverse.length.to_s;  
  puts "Time:" + (Time.now - t1).to_s;
Результат:
etf@etf-desktop:~/prog/RubyApplication2/lib$ time ruby main.rb 10000000
Result:50000000
Time:0.734442

real    0m0.760s
user    0m0.560s
sys     0m0.196s
Итак, подведем неутешительные итоги нашего исследования:
ImplementationTimeRatio
Ruby0.7344421
Java (StringBuffer)0.9361.27
Java (StringUtils)2.2333.04
---------------- Now playing: Pink - Conversations With My 13 Year Old Self via FoxyTunes

Nov 17, 2007

JavaFX: Связываем аттрибуты разных классов.

Одной из интересных возможностей JavaFX является связывание атрибутов. Для этого используется ключевое слово inverse. Если интерпретатор JavaFX встречает ключевое слово inverse в описании атрибута класса, он автоматически обновляет (вставка, удаление замена) соотвествующий (связанный атрибут). Рассмотрим несколько примеров. Первый взят из официального описания языка (The JavaFX Script Programming Language): class Person { attribute name: String; attribute parent: Person inverse Person.children; attribute children: Person* inverse Person.parent; function getFamilyIncome(): Number; function getNumberOfChildren(): Number; operation marry(spouse: Person); } В данном случае изменение атрибута children повлечет изменение атрибута parent соответствующего объекта. Вот как это будет выглядеть: var pp:Person = Person {name: "Parent"}; var pc1:Person = Person {name: "Child1"}; var pc2:Person = Person {name: "Child2"}; insert pc1 into pp.children; pc2.parent = pp; p("pc1 = {pc1}"); p("pc2 = {pc2}"); p("pp = {pp}"); В консоле мы получим следующее: pc1 = Person {name: 'Child1' parent: Person {name: 'Parent' parent: null children: [Person ... Person {name: 'Child2' parent: Person ... children: []}]} children: []} pc2 = Person {name: 'Child2' parent: Person {name: 'Parent' parent: null children: [Person {name: 'Child1' parent: Person ... children: []} Person ...]} children: []} pp = Person {name: 'Parent' parent: null children: [Person {name: 'Child1' parent: Person ... children: []} Person {name: 'Child2' parent: Person ... children: []}]} Как видно, добавление нового объекта pc1 в коллекцию объекта pp автоматически обновляет атрибут pc1.parent. И, соотвественно, когда мы указывает значение атрибута parent у объекта pc2 - от он автоматически добавляется в коллекцию pp.children.

Oct 21, 2007

Planshet

В качестве безвозмездной помощи своему текущему проекту, сделал небольшую презентационную программку. Основная ее задача - отображать различную полезную информацию на "большом" мониторе так, чтобы вся команда могла это видеть. В качестве языка для данной разработки был выбран скрипт JavaFX. Так как сделать хотелось быстро, а особых требований к надежности или ресурсоемкости не было. В проекте присутствуют следующие классы:
  • ChangeImageSlide – слайд, который показывает все картинки из папки
  • ImageSlide – слайд, который показывает одну фиксированную картинку
  • Planshet – основная логика программы
  • Release – показывает заголовок и дату доставки
  • Scenario – класс, содержит сценарий презентации
  • StatusSlide – слайд, отображает статус автоматической сборки (CruiseControl), через rss.
Скачать исходный код можно на сайте: http://code.google.com/p/planshet/

Oct 12, 2007

Элементы функционального программирования на JavaFX

Похоже в JavaFX проявляется много новых (для Java платформы) особенностей. Например элементы функционального программирования. JavaFX поддерживает описание «чистых» функций с помощью ключевого слова function. Такая функция может содержать только последовательность определений переменных и возврат значения. Предполагается, что такая функция только вычисляет некий результат и не имеет никакого побочного действия (в отличие от процедур).
Кроме этого на JavaFX легко и красиво реализуются так называемые замыкания. Замыкание — это особый вид функции. Она определена в теле другой функции и создаётся каждый раз во время её выполнения. В записи это выглядит как функция, находящаяся целиком в теле другой функции. При этом вложенная внутренняя функция содержит ссылки на локальные переменные внешней функции. Каждый раз при выполнении внешней функции происходит создание нового экземпляра внутренней функции, с новыми ссылками на переменные внешней функции. Вот простой пример такой функции:
function getF(b:Boolean) {
    return function (n:Integer) = if b then n-1 else n+1;
}

var fInc = getF(true);
var fDec = getF(false);

var a = 10;
var b = 10;

p(fInc(a));
p(fDec(b)); 
Результатом работы такого скрипта будет:
compile thread: Thread[AWT-EventQueue-0,6,main]
compile 0.031
9
11

Sep 12, 2007

JavaFX Basics (Part 2)

Прежде всего, JavaFX поддерживает как процедурную так и декларативную нотацию. Очевидно, что декларативный подход очень удобен при описании графического интерфейса. Попробую сделать краткий обзор основных возможностей и особенностей языка. Но тем не менее, рекомендую посетить сайты с оригинальной документацией, ссылки на которые я приводил в предыдущей статье.
Основные типы данных. JavaFX поддерживиет всего несколько основных типов данных:
  • String - java.lang.String
  • Boolean - java.lang.Boolean
  • Number - java.lang.Number
  • Integer - byte, short, int, long, java.math.BigInteger
Для описания массивов можно использовать оператор мощности. Он записывается следующим образом: ? - значение опционально (иожет быть null) + - одно или более значений * - любое количество значений Несколько примеров описания переменных:
var str:String = "Hi!"; var strs:String* = ["String1","String2","String3"];
Что касается массивов, то все они одномерные. То есть мы можем записать что то вроде:
var arr = ["Str 1 ","Str 2 ",["Str 31 ","Str 32 ","Str 33 "],"Str 4 "];
Но если мы попытается просмотреть содержимое переменной arr, то увидим, что это обычный плоский массив, совершенно идентичный следующей записи:
var arr = ["Str 1 ","Str 2 ","Str 31 ","Str 32 ","Str 33 ","Str 4 "];
Декларативная нотация. Другим интересным свойством языка является возможность использования декларативного подхода. Особенно впечатляет использования этого подхода при описании пользовательского интерфейса. Допустим у нас есть некий класс Customer, который содержит строковое свойство Name и числовое свойство Identity, тогда создать новый экземпляр класса мы можем следующим образом:
class Customer { attribute Name:String; attribute Identity:Integer; } var currentCustomer = Customer {Name: "Google" Identity: 1};

JavaFX Magic Numbers

Думаю любой программист испытывает дискомфорт, когда встречает в коде различного рода "магические цифры". JavaFX, похоже, содержит ряд "плохо документированных" констант. Я решил немного исследовать эту тему.
  • __DIR__ -- возвращает url каталога, в котором находится текущий исполняемый файл (скрипт). Это может быть url внутри jar, если скрипт находится внутри.
  • __FILE__ -- возвращает url текущего исполняемого файла.
  • __LINE__ -- Возвращает номер строчки, которая выполняется в данный момент.
  • __ARCHIVE__ -- возвращает url архива (jar), из которого выполняется данный файл (если такой вообще есть).
Просмотреть конкретные значения этих констант можно с помощью нехитрой программы:
import javafx.ui.*;
  
Frame {
    title  : 'Magic Constants'
    width  : 700
    height : 400
    content: Label {text: "<html><dl>
                           <dt>__DOCBASE__</dt><dd>{__DOCBASE__}</dd>
                           <dt>__DIR__</dt>    <dd>{__DIR__}</dd>
                           <dt>__FILE__</dt>   <dd>{__FILE__}</dd>
                           <dt>__LINE__</dt>   <dd>{__LINE__}</dd>
                           <dt>__ARCHIVE__</dt><dd>{__ARCHIVE__}</dd>
                           </dl></html>"}
       
    visible: true
}// Frame
Источник информаци : "Magic Constants" From Planet JFX

Sep 8, 2007

Firewall on Ububtu

Совсем недавно решил переустановить систему на своем основном компьютере (домашнем). До этого там стояла MS Windows XP. Но работала она очень плохо. Были очень неприятные проблемы. Самой ужасной - перезагрузка системы во время работы. В самые неожиданные моменты. Это очень похоже на проблемы с железом. Программы диагностики особо ничего не выявили. Одним радостным днем системе стало совсем плохо. При попытке войти в систему под любым пользователем она перегружалась. Я решил, что не буду пытаться ее восстанавливать (тем более что файлы были доступны удаленно и всю информацию можно было спасти), а просто переустановлю. Причем в качестве новой системы я выбрал линукс. Он не так сильно напрягает меня, а дома у меня нет особой нужды в программах под альтернативную платформу. Как Java Developer мне вообще не слишком важна целевая платформа. Наиболее актуальный для меня дистрибутив в данный момент SUSE. Я считаю его наиболее стабильным и отполированным. Более того, в этом дистрибутиве идет, не побоюсь этого слова, самый совершенный редактор настроек. Ну если не считать, конечно, прямого редактирования конфигурационных файлов. Однако, последнее время я слышу много восторженных криков по поводу Ubuntu. У этого дистрибутива хорошие, крепкие корни, большое число поклонников, но уж очень много PR. Я всегда с большой опаской отношусь, к продуктам, которые особенно активно рекламируют. Тем не менее, я решил попробовать. Не буду глубоко вдаваться в подробности, кратко выскажу свое мнение. Прежде всего этот дистрибутив абсолютно не тянет на почетное звание лучший desktop. У него огромное количество проблем. Встроенные средства конфигурации не покрывают и 10% системы. А то что покрыто, покрыто очень плохо. Доработка напильником требуется на каждом углу. Я был удивлен, когда мне говорили, что убунта не годится для новичков. Теперь мне стало понятно. Но я не могу не сказать, что общее впечатление от дистрибутива очень положительное. Это не Fedora, которую вообще противно использовать в качестве рабочей станции. (О серверах речи нет). Поэтому я довел начатое до логического конца и привел систему к состоянию, в котором ее реально использовать. Я хочу подчеркнуть, что проблем было довольно много, но все они решались легко. Решение было либо очевидными, либо легко находилось в документации, доступной в сети. Основные проблемы, на сколько я помню, можно выразить следующим списком:
  • Установка необходимого ПО и библиотек для проигрывания музыки и видео.
  • Установка проприетарных драйверов (видео).
  • Установка 3D рабочего стола.
  • Подключение к сети (странная проблема, сеть подключалась через раз).
  • Шрифты/ кодировки.
Как вы видите - проблемы тривиальные, и особых трудностей не вызвали. Хочу сосредоточиться на специфике моего случая. Основной компьютер подключен к внешней и внутренней сетям. Он выполняет функции брандмауэра. Поэтому встал вопрос доступа к Интернету из внутренней сети. Конечно, самый прямой способ это настройка конфигурации iptables. То есть включение masquerading/NAT. Кроме того, мне нужен DHCP сервер для внутренней сети, чтобы я не напрягался со статическими адресам и не менял настройки рабочего ноутбука. Итак имеем две проблемы:
  • DHCPd
  • Firewall + NAT
По прямому пути я не пошел, ведь у меня в руках самая дружественная система в мире. Прежде всего многих новичков очень пугает отсутствие возможности зайти под root. Точнее, пугает тот факт, что пароль супер пользователя неизвестен. При этом попытка произвести любое административное действие приводит к запросу пароля. Дело в том, что в Ubuntu используется немного другой подход, основанный на sudo. В чем его суть? Если не вдаваться в подробности, на все вопросы надо отвечать своим пользовательским паролем. Если есть необходимость запуска некой программы из консоли, но с правами root, надо выполнить следующий финт: sudo <название программы> Вас опять попросят ввести пароль - ВАШ ПАРОЛЬ! Одним словом все просто и прекрасно. Теперь вернемся к нашим проблемам. Установка dhcpd не вызывает особых проблем. Можно воспользоваться Synaptic - встроенным менеджером пакетов (не супер, но достаточно удобно и надежно). Либо прямо в консоль ввести sudo apt-get install dhcpd. Для особого удобства можно установить какую-нибудь программу для конфигурации этого демона. Самое интересное (для меня) второй пункт. На сколько это удобно можно сделать в Ubuntu. Решений много, я остановился на Firestarter. Это ПРЕДЕЛЬНО ПРОСТОЙ конфигуратор брандмауэра. Все сводится к простейшему визарду. Более того! Ferestarter берется настроить даже DHCP для внутренней сети. Однако в моем случае, возник небольшой конфликт. Так как установленный в системе демон и тот который хотел использовать Firestarter отличались версиями. Я не слишком расстроился, так как эта функция у меня уже и так работала, поэтому я просто пропустил настройку dhcp в Firestarter. Еще более приятным сюрпризом, для меня была возможность Firestarter показывать активные подключения и на лету модифицировать правила фильтрации. Но меня ждал один подвох. Как оказалось, я не могу войти из внутренней сети в корпоративный VPN. Это меня сильно огорчило. Тем более, что разработчики обещают исправить эту проблему только в следующем релизе Firestarter. Однако (как всегда!!!) решение есть. Причем достаточно прямое. Необходимо внести небольшую правку в один из конфигурационных файлов Firestarter. Открываем терминал и выполняем следующую магическую последовательность: # sudo -i < вводим СВОЙ пароль> # chmod +w /etc/firestarter/user-pre # gedit /etc/firestarter/user-pre В открывшемся редакторе вводим следующий текст: # Forward PPTP VPN client traffic $IPT -A FORWARD -i $IF -o $INIF -p tcp --dport 1723 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT $IPT -A FORWARD -i $IF -o $INIF -p 47 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT $IPT -A FORWARD -i $INIF -o $IF -p 47 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT Затем выполняем: # chmod -w /etc/firestarter/user-pre # /etc/init.d/firestarter restart После всех этих действий я получил возможность полноценно работать из внутренней сети. Буду рад, если эта статья кому-то поможет побороть его проблемы. PS. Вот уже прошел месяц использования дистрибутива Ubuntu. Какие выводы можно сделать. Прежде всего дистрибутив работает. И в нем можно работать. Ошибок в программах довольно много, но проблемы решаемые и особо не раздражают пользователя (меня) у которого нет времени долго и глубоко копать. Из оставшихся проблем - поддержка микрафона и skype. Удалось заставить работать и то и другое, но ... работают они не очень красиво. Добиться желаемого поведения на 100% мне не удалось.

Aug 24, 2007

JavaFX Introduction (Part 1)

В одной из презентаций наткнулся на восторженные крики про JavaFX. По началу вообще не обратил особого внимания. Но когда эти крики повторились несколько раз, пришлось задуматься. Решил разобраться, что это за зверь и с чем его едят. Вышел на официальную страницу JavaFX Overview. Честно признаюсь - ничего не понял. Нет, конечно, понял, что это очень круто, глобально и должно совершить очередную революцию. Но больше ничего. Это меня очень огорчило и я решил копать дальше (так быстро сдаваться я не привык)... Ну достаточно лирики. Перейдем непосредственно к делу. Постараюсь максимально кратко и ясно рассказать о том, что я выяснил, и сделать некоторые выводы. Сразу оговорюсь, информации (дельной информации!!!) очень мало. Поэтому сразу приведу короткий список полезных ссылок по теме, которые я сумел найти:
  • Introduction to JavaFX Script - достаточно хорошее введение в основы javaFX (немного устарело и не все примеры работают)
  • Project OpenJFX - официальная страничка проекта openjfx
  • Planet JFX - сборник ссылок по теме
  • Chris Oliver's Weblog - блог одного из разработчиков javaFX. Тут можно узнать последние новости, возможности javaFX, которые только были залиты в cvs. Здесь есть информация по F3 - прямому предку javaFX. Очень советую внимательно изучить этот ресурс.
  • JavaFX API - справочник по javaFX API (описание многих объектов неполное)
Скажу так, особо глубокой документации я не нашел. Все отрывочно и поверхностно. Это и не удивительно. Платформа находится в стадии альфа версии. Структура классов, сигнатуры методов еще не заморожены и меняются. Естественно, документация не успевает обновляться, многие области вообще не покрыты. Итак, javaFX - это новый скриптовой язык от SUN. Нужно, конечно, иметь в виду, что он не очень похож на большинство скриптовых языков. То есть, он выполняется интерпретатором, но вот тех возможностей, которые дает нам интерпретатор, там практически и нет. Зато в еще более зачаточном состоянии находится компилятор для javaFX, который, по предварительным оценкам может дать прирост производительности в районе 50 раз. Поэтому фактически javaFX - скриптовой язык, но я бы не думал о нем в таком ракурсе. Сам собой напрашивается вопрос: зачем нам ЕЩЕ один скриптовой язык? Вопрос хорошо. Он возникает при известии о каждом новом скриптовом языке. Но похоже в данном случае, у SUN на его счет огромные планы. Основное назначение этого языка - динамические графические интерфейсы. Сейчас есть много примеров воссоздания сложных динамических сайтов с помощью javaFX. Лично я особого смысла в этом не вижу, я вообще сторонник строгого интерфейса, но ... иногда бывает надо. Ну и в завершении этой обзорной части небольшой неутешительный вывод. Надо ли нам начинать новые проекты с использованием javaFX. Я думаю - еще нет. Еще нет нормальной поддержки этой технологии со стороны IDE. Существуют плагины для eclipse и netBeans, но их уровень оставляет желать лучшего. Для меня наиболее удобным инструментом для работы с javaFX оказался, написанный на нем же, JavaFXPad.

Aug 9, 2007

Сбылась очередная мечта идиота!

Давно хотел сделать так, чтобы не главной страниче публиковалась только вступительная часть статьи. А полный текст открывался по специальной ссылке. Это красиво и удобно. Знаю как это сделать на старом движке. Но сам то использую новый. А главное - надо перелапачивать все посты... Вот в этом новом блоге - сразу сделал эту фичу и доволен как слон :). Для тех кто "еще кипятит" есть чудесная ссылка с описанием: vonderer@darkstar:~$: Blogger beta и пара советов.

Пробный пост...

Решил выделить отдельный блог для "умных" статей. Ясное дело, что особо времени на бумагомарательство нет, так что новостей и прочих copy-paste ерунды тут практически не будет. Думаю делать здесь некоторые заметки по своим исследованиям и экспериментам... Посмотрим, что из этого получится.