На выходных дошли руки, наконец-то, опробовать производительность другого аспекта миграции с PHP на Java. Мне нужен был ORM, да не просто ОРМ, а ОРМИЩЕ! О hibernate я слышал давно и все отзывы хорошие, да и к тому же Spring прекрасно с ним дружит. На этом и остановился — ман по hibernate + попытка ввинтить его в примитивное SpringMVC приложение вылилось следующими синтетическими тестами:
В качестве испытуемого было выбрана хорошо мне знакомая MySQL. В каждом ORM создавался примитивный объект User:
package domain; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="users") public class User { @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="id") private Long id; private String email; public Long getId() { return this.id; } public User() {} public User( String email ) { this.email = email; } public String getEmail() { return this.email; } public void setEmail(String email) { this.email = email; } }
и в PHPDoctrine:
< ?php class User extends Record { public function setTableDefinition() { $this->setTableName( 'users' ); $this->hasIdColumn(); $this->hasColumn( "email", "string", array( "notnull" => TRUE ) ); } public function setEmail( $email ) { $this->email = $email; return $this; } public function getEmail() { return $this->email; } public function getId() { return $this->id; // свойство вымышлено - в Doctrine для этого нужны танцы и бубен } }
Далее шло тестирование вставки и чтения новых объектов в БД.
Результаты:
1000 вставок
Hibernate ~11сек
Doctrine ~1.4сек
Чтение 2000 записей из БД и создание их сущностей
Hibernate ~0.4сек
Doctrine ~1.16сек
Не понятно откуда такая большя разница при вставке, но что-то мне подсказывает, что Hibernate (или спринговский HibernateTemplate) по-умолчанию оборачивает методы записи в транзакции. Пока что не разобрался как их отключить или настроить, посему просто привожу часть конфигурации сервлета:
[...skipped...] <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="myDataSource"/> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.hbm2ddl.auto">create</prop> </props> </property> <property name="annotatedClasses"> <list> <value>domain.User</value> </list> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"> <ref local="sessionFactory" /> </property> </bean> <bean id="hibernateInterceptor" class="org.springframework.orm.hibernate3.HibernateInterceptor"> <property name="sessionFactory"><ref local="sessionFactory"/></property> </bean> [...skipped...]
Кстати хочу обратить ваше внимание на то, что в Java называется POJO(Plain Old Java Objects). Этим термином называют классы, которые самодостаточны, а значит переносимы; то-есть они не наследуют никаких базовых классов, протиктованых фреймворками и не реализуют никаких интерфейсов. Таким образом класс User выглядит более самостоятельным в Java, чем его брат в PHP, которому пришлось унаследоваться от Record, использовать метод setTabkeDefinition, для описания связей, и навсегда забыть о родном конструкторе, так как он нужен Doctrine для внутренних нужд.
Спасибо за пост. Сам давно уже задумался над тем чтобы выучить java. Да всё времени не хватает. А doctrine полностью доволен.
В Doctrine 2.0 будут POHO — тоже ничего не надо будет наследовать, а маппинги будут задаваться с помощью аннотаций. Я считаю, что это будет большой прорыв среди ОРМ-движков для PHP.
А с чем связан переход на джаву?
Тут прорыв больше в РНР5.3 и старше, когда разрешили в рефлексиях получать доступ к закрытым свойствам объектов.
Единственно чего я боюсь, что используя повсеместно доступ через рефлексию, не пострадает ли производительность еще больше?
А на java я решил переходить по многим причинам, но основная из них — java гараздо строже PHP.
Как на счёт Python?
А он тут при чем?
Алексей, а можете привести пример, показывающий преимущество строгости?
Благодарю.
привожу.
над проектом работает N человек.
в проекте есть класс с методом A(). метод принимает три аргумента:
a, b, c
в случае PHP необходимо либо написать PHPDoc и воспользоваться IDE умеющей читать этот блок, либо пойти в метод и изучить что он делает и как. В типизированых языках не нужно себя насиловать описанием типов переменных и любая IDE сможет дать адекватную подсказку. + исключены ситуации случайной передачи неверного типа в метод.
пример номер два — перегрузка. То как она реализована в РНР сейчас — убожество.
Начнём с того что в PHP вообще перегрузки как таковой нету.
А чем тебя смущает Function(MyObject $var, array $varArr, MyObjectSecond $var2) ?
тем, что есть еще и примитивные типы данных
[...] несколько месяцев назад я уже проводил тест производительности двух сабжевых продуктов. Тогда я, правда, оговорился в [...]