)测试结果
map类型 |
测试数据量 |
测试类型 |
总耗时(ns) |
平均耗时(ns) |
原生map |
10000 |
put |
100 |
1.000000e-02 |
堆外map |
同上 |
put |
4800 |
4.800000e-01 |
基于磁盘map |
同上 |
put |
345000 |
3.450000e+01 |
基于磁盘-内存映射map |
同上 |
put |
6000 |
6.000000e-01 |
原生map |
同上 |
get |
100 |
1.000000e-02 |
堆外map |
同上 |
get |
2000 |
2.000000e-01 |
基于磁盘map |
同上 |
get |
75400 |
7.540000e+00 |
基于磁盘-内存映射map |
同上 |
get |
1100 |
1.100000e-01 |
3)结论
①原生的基于堆的map速度始终是最快的
②堆外map和基于磁盘且开启了内存映射的map相比,优势较小。至于原因,有待深入理解。
③对于“基于磁盘-内存映射map”,使用“fileMmapEnableIfSupported”配置,对性能影响较大,建议直接开启。配置“fileMmapPreclearDisable”对于put的性能提升较大(约一倍提升)。
MapDB事务
MapDB是支持事务的,具体使用如下:
package me.lovegao.mapdb.hello;
import java.util.concurrent.ConcurrentMap;
import org.mapdb.DB;
import org.mapdb.DBMaker;
import org.mapdb.Serializer;
public class MapDBTransaction {
public static void main(String[] args) {
DB db = DBMaker
.fileDB("file3.db")
.fileMmapEnable()
.transactionEnable()
.closeOnJvmShutdown() //JVM关闭时关闭db
.make();
ConcurrentMap<String,Long> map = db
.hashMap("mapsl3", Serializer.STRING, Serializer.LONG)
.createOrOpen();
map.put("a", 1L);
map.put("b", 2L);
db.commit();
System.out.println(map.get("a"));
System.out.println(map.get("b"));
map.put("c", 3L);
System.out.println("rollback之前,c:" + map.get("c"));
db.rollback();
System.out.println("rollback之后,a:" + map.get("a"));
System.out.println("rollback之后,c:" + map.get("c"));
}
}
运行结果:
1
2
rollback之前,c:3
rollback之后,a:1
rollback之后,c:null
因为配置了closeOnJvmShutdown,所以再次运行时能够正常运行。
如果去掉了transactionEnable和closeOnJvmShutdown,再次运行时将出现以下异常:
Exception in thread "main" org.mapdb.DBException$DataCorruption: Header checksum broken. Store was not closed correctly and might be corrupted. Use `DBMaker.checksumHeaderBypass()` to recover your data. Use clean shutdown or enable transactions to protect the store in the future.
at org.mapdb.StoreDirectAbstract.fileHeaderCheck(StoreDirectAbstract.kt:113)
at org.mapdb.StoreDirect.<init>(StoreDirect.kt:114)
at org.mapdb.StoreDirect$Companion.make(StoreDirect.kt:57)
at org.mapdb.StoreDirect$Companion.make$default(StoreDirect.kt:56)
at org.mapdb.DBMaker$Maker.make(DBMaker.kt:450)
at me.lovegao.mapdb.hello.MapDBTransaction.main(MapDBTransaction.java:17)
最后说以下,fileDB("file3.db")这里的路径可以指定其他目录,默认是在项目的根目录下。
路径是自己创建的,文件是MapDB自动创建的,切记不要多此一举,把文件也创建了,那样会报错的。