我发现这种方法非常适合我,但需要大量内存。由于其他设计要求,我必须通过类似Vector-HashTable的结构进行比较,而不是通过数据库端的过程。
有人有优化建议吗?最佳解决方案应该与我现在正在做的相似,因为大部分代码已经围绕它设计。
谢谢
对于两个结果集,请使用相同的“ORDER BY”子句(基于“key”)进行指定。然后,您只需要同时在内存中保留每个结果集中的一条记录。
例如,假设您的结果是res1
和res2
。
如果res1
的key
字段小于res2
的key
字段,则res2
缺少一些记录;请迭代res1
,直到它的key
字段等于或大于res2
的key
。
同样,如果res1
的key
字段大于res2
的key
字段,则res1
缺少一些记录;请改为迭代res2
。
如果当前记录的key
字段相等,则可以比较它们的值,然后迭代两个结果集。
通过这种方式,您可以看到在任何给定时间只需要保留每个结果中的一条记录。
您是否了解享元模式?您是否有许多相等的对象?也许这个模式对于您的“Key”是合适的,因为我想每一行都会重复使用字段名称。如果它们是字符串,您可以调用intern()
使它们与其他相等的字符串共享同一个内存位置,因为字符串是不可变的。
另一个可能的优化——不是内存而是速度——如果并发不是问题,那么使用ArrayList
而不是Vector
可能会更快,因为它们没有同步,所以访问应该会更快。同样,HashMap
没有同步,而Hashtable
有同步,因此使用前者可能也会更快。
class RowHash {
private final int id; // the row id
private final int hashCode; // summary of the whole row info
public RowHash( ResultSet rs ) {
this.id = rs.getInt("id");
// get the strings from all the data
this.hashCode = new StringBuilder()
.append( rs.getString("field1") )
.append( rs.getString("field2") )
.append(rs.getString("fieldN"))
.toString().hashCode();
}
public final boolean equals( Object other ) {
return this.hashCode() == other.hashCode();
}
public final int hasCode() {
return hashCode;
}
}
...
ResulSet rs = ...
while( rs.next() ) {
arrayList.add( new RowHash( rs ) );
}
intern()
。intern
在该answer上进行前/后截图。
Before
之后
蓝色区域表示使用的内存,在第一次使用时为2GB左右,在第二次使用时不到25MB。
你可以封装你自己的对象,例如一个比HashMap更小的'MyRecord',然后它将成为'MyRecord'列表。
如果必须使用HashMap,请使用new HashMap(7,1)而不是默认构造函数,这可以节省内存,因为你说在一个map中有固定的“8个键值对”。
如果您没有足够的内存,您将需要外部存储来支持您的数据结构,这很难正确地完成(弱引用映射到您的数据,所有这些都需要滚动到磁盘等),并且在扩展时可能仍然会出现性能问题。
如果您真的有大量的数据,我建议嵌入一个SQL数据库。然后,您可以生成两个包含您的数据的表,并要求数据库查找任何差异,然后删除这些表。我之前使用过Derby,我觉得它不错,但还有其他选择。