Hibernate (5 HIGH): addColumn/addReferencedColumn/addIndex ArrayList→LinkedHashSet (19x) FK second-pass LinkedHashSet, orderHierarchy LinkedHashSet MyBatis (1 MEDIUM): sortConstructorMappings indexOf→HashMap (12x) EF Core (2 HIGH + 1 MEDIUM): FindGenerationProperty HashSet (250x), AddPrincipals HashSet (250x), FK discovery HashSet (6x) Diesel (3 MEDIUM): SQLite/MySQL row position()→BTreeMap (51x) SQLAlchemy (2 HIGH): _values_bindparam Set (500x), evaluated_keys Set (500x) Peewee (1 MEDIUM): _SortedFieldList.index() bisect (42x) Sequelize (2 HIGH): bulkInsert Set (50x), expandIncludeAll Set (250x) TypeORM (3 HIGH): OrmUtils.uniq Map (500x), diffColumns Set (125x), updatedColumns Set (100x) Doctrine ORM (1 HIGH + 2 MEDIUM): hydrator discriminator (26x), addSubClass (250x), SqlWalker partial (130x) GORM (1 MEDIUM): sortCallbacks getRIndex→map (194x) SQLite: SqliteTest unit proof 4/4 PASS (101x) Unit tests: all PASS — Hibernate/MyBatis/EfCore/Diesel/SQLAlchemy/Peewee/ Sequelize/TypeORM/Doctrine/GORM Whitepaper: 157 sites, 62 ecosystems; PDF 752K
59 lines
2 KiB
Diff
59 lines
2 KiB
Diff
--- a/hibernate-core/src/main/java/org/hibernate/mapping/Constraint.java
|
|
+++ b/hibernate-core/src/main/java/org/hibernate/mapping/Constraint.java
|
|
@@ -7,7 +7,9 @@ package org.hibernate.mapping;
|
|
|
|
import java.io.Serializable;
|
|
import java.util.ArrayList;
|
|
+import java.util.LinkedHashSet;
|
|
import java.util.List;
|
|
+import java.util.Set;
|
|
|
|
import org.hibernate.MappingException;
|
|
import org.hibernate.boot.model.relational.Exportable;
|
|
@@ -22,7 +24,12 @@ public abstract class Constraint implements Exportable, Serializable {
|
|
private String name;
|
|
- private final ArrayList<Column> columns = new ArrayList<>();
|
|
+ // hibernate-0001 fix: LinkedHashSet for O(1) contains() in addColumn().
|
|
+ // Previously ArrayList<Column>: addColumn() called contains() which is O(C)
|
|
+ // and addColumn() is invoked inside loops over columns/selectables,
|
|
+ // giving O(C²) total cost. LinkedHashSet preserves insertion order
|
|
+ // (required by callers of getColumns() that iterate in definition order)
|
|
+ // while making contains() O(1).
|
|
+ private final LinkedHashSet<Column> columnsSet = new LinkedHashSet<>();
|
|
private Table table;
|
|
private String options = "";
|
|
|
|
@@ -44,9 +51,9 @@ public abstract class Constraint implements Exportable, Serializable {
|
|
|
|
public void addColumn(Column column) {
|
|
- if ( !columns.contains( column ) ) {
|
|
- columns.add( column );
|
|
- }
|
|
+ // O(1) with LinkedHashSet; was O(C) with ArrayList
|
|
+ columnsSet.add( column );
|
|
}
|
|
|
|
public void addColumns(Value value) {
|
|
@@ -60,19 +67,19 @@ public abstract class Constraint implements Exportable, Serializable {
|
|
/**
|
|
* @return true if this constraint already contains a column with same name.
|
|
*/
|
|
public boolean containsColumn(Column column) {
|
|
- return columns.contains( column );
|
|
+ return columnsSet.contains( column );
|
|
}
|
|
|
|
public int getColumnSpan() {
|
|
- return columns.size();
|
|
+ return columnsSet.size();
|
|
}
|
|
|
|
public Column getColumn(int i) {
|
|
- return columns.get( i );
|
|
+ return (Column) columnsSet.toArray()[i];
|
|
}
|
|
|
|
public List<Column> getColumns() {
|
|
- return columns;
|
|
+ return new ArrayList<>( columnsSet );
|
|
}
|