Некто Sujit Pal в своем блоге привел результаты сравнения производительности нескольких агентных фреймворков для Java (сравнивались Kilim, Jetlang, Actor Guild, ActorFoundry, а так же Scala Actors из стандартной библиотеки языка Scala). Двумя наиболее быстрыми фреймворками оказались Kilim и Jetlang. Поскольку в блоге были опубликованы исходные тексты тестового приложения для Kilim, то я сравнил скорость работы SObjectizer 4.4.0-beta6 с Kilim 0.50.
На моей машине (Intel Core2Duo 2GHz, 2Gb RAM, WinXP) Kilim-приложение отработало за 12.870 секунды, а SObjectizer-приложение – за 11.828 (обе цифры являются усредненными по нескольким запускам результатами). В качестве JVM использовалась клиентская Java-машина из состава Java 1.6.0_07. SObjectizer-приложение компилировалось с помощью Visual C++ 2005. В процессе работы Kilim-приложение потребляло до 170Mb памяти, а SObjectizer-приложение – до 80Mb. Вот исходный текст SObjectizer-приложения.
Результаты тестов меня, честно говоря, несколько расстроили. Я рассчитывал на более серьезное преимущество SObjectizer за счет использования нативного кода. Но, видимо, в данном тесте, где создается большое количество мелких объектов-строк, сборщик мусора в Java делает выделение динамической памяти гораздо более быстрым, чем в C++.
Тем не менее, результат не самый плохой. Особенно с учетом того, как сообщения отсылаются в Kilim и в SObjectizer. В Kilim актеры должны владеть ссылками на конкретные объекты mailbox-ы, непосредственно в которые сообщения и помещаются. Тогда как в SObjectizer при отсылке сообщения есть только строковое имя агента-владельца сообщения, по которому SObjectizer сам находит получателя сообщения. Т.е. при отсылке сообщений в SObjectizer4 выполняется больше работы, чем в Kilim. Кроме того, в SObjectizer существуют понятия состояний и событий, которых нет в Kilim. А на работу с этими сущностями в SObjectizer так же тратится время и ресурсы.
Отдельно хотелось бы отметить один важный, на мой взгляд, момент. В упомянутых Java/Scala фреймворках процесс выборки сообщений агентами выглядит очень примитивным. Это обычный цикл, в начале которого из mailbox-а извлекается очередной объект-сообщение, после чего в виде if-ов, switch-ей или pattern matching-а (как в Scala) определяется, что же с этим сообщением нужно делать. Лично мне такой подход не нравится, я считаю его утомительным в написании, он череват ошибками и он сложен при сопровождении чужого кода. Я в очередной раз убедился, что лучше, когда фреймворк берет на себя задачу сопоставления очередного сообщения конкретному методу объекта.
Проведение данного сравнения так же привело меня к следующим выводам:
1. Ясно видно, что модель актеров сейчас стремительно набирает популярность. Об этом свидетельствует рост внимания к языку программирования Erlang, большое количество рассуждений на тему удобства модели актеров в блогах, растущее количество агентных фреймворков для Java. И это хорошо, т.к. формируется благоприятная для SObjectizer среда.
2. Если в области управляемых (managed) языков вроде Java/Scala/Python/Ruby наблюдается рост разнообразных (по мнению их авторов) агентных фреймворков, то для C++ такого роста не видно вообще. Что, на мой взгляд, благоприятно для SObjectizer – C++ умирать пока не собирается, и в C++ приложениях можно получить выгоды от использования модели актеров. Поэтому имеет смысл развивать SObjectizer именно как C++ инструмент.
3. В SObjectizer нужно вводить механизмы обмена сообщениями, которые не требуют поиска получателя сообщения по имени. Например, что-то типа mailbox-ов, как в Kilim, или каналов (channels, pipelines). Т.е. если двум агентам нужно обмениваться сообщениями друг с другом, они создают объект-канал, ссылка на который есть у обоих. И для отсылки сообщений они используют не send_msg, а метод записи сообщения в канал. Тем более, что каналы могут применяться так же для контроля за переполнением очереди сообщений агента.