在我的桌面应用程序中,新数据库经常打开.我使用Hibernate/ JPA作为ORM.问题是,创建EntityManagerFactory速度相当慢,在快速机器上花费大约5-6秒.我知道它EntityManagerFactory应该是重量级的,但对于用户希望快速打开新数据库的桌面应用程序来说这太慢了.
我可以关闭一些EntityManagerFactory功能来更快地获取实例吗?或者是否可以懒惰地创建一些EntityManagerFactory来加速cration?
在知道数据库url之前,我可以以某种方式创建EntityManagerFactory对象吗?我很乐意关闭所有可能的验证.
通过这样做,我可以集合EntityManagerFactorys供以后使用吗?
任何其他想法如何更快地创建EntityManagerFactory?
更新更多信息和JProfiler分析
桌面应用程序可以打开保存的文件.我们的应用程序文档文件格式包含1个SQLite数据库+以及ZIP文件中的一些二进制数据.打开文档时,将解压缩ZIP并使用Hibernate打开数据库.数据库都具有相同的模式,但显然有不同的数据.
看来我第一次打开文件时需要比以下时间长得多.我用JProfiler描述了第一次和第二次运行并比较了结果.
第一轮:
create EMF: 4385ms
build EMF: 3090ms
EJB3Configuration configure: 900ms
EJB3Configuration <clinit>: 380ms
Run Code Online (Sandbox Code Playgroud)
.
第二轮:
create EMF: 1275ms
build EMF: 970ms
EJB3Configuration configure: 305ms
EJB3Configuration <clinit>: not visible, probably 0ms
Run Code Online (Sandbox Code Playgroud)
.
在调用树比较中,您可以看到某些方法明显更快(DatabaseManager.作为起点):
create EMF: -3120ms
Hibernate create EMF: -3110ms
EJB3Configuration configure: -595ms
EJB3Configuration <clinit>: -380ms
build EMF: -2120ms
buildSessionFactory: -1945ms
secondPassCompile: -425ms
buildSettings: -346ms
SessionFactoryImpl.<init>: -1040ms
Run Code Online (Sandbox Code Playgroud)
热点比较现在有了有趣的结果:
.
ClassLoader.loadClass: -1686ms
XMLSchemaFactory.newSchema: -184ms
ClassFile.<init>: -109ms …Run Code Online (Sandbox Code Playgroud) 我们在Android应用程序中使用加载Google Guava LoadingCache作为位图.在应用程序中,我正在运行一个绘图线程,它将缓存中的位图绘制到Canvas.如果特定位图不在缓存中,则不会绘制它,因此任何加载都不会阻止绘制线程.
然而,这种绘画导致视觉口吃,每秒帧速率不是我们想要的.我把它钉getIfPresent()在了缓存的方法上.仅此一项占应用总CPU时间的20%.在getIfPresent() LocalCache$Segment.get()需要的时间超过80%:

请记住,这只是一个已经存在的位图的查找.永远不会发生负担get().我认为get()LRU队列会有一个簿记开销,它决定了如果段已满就会发生哪些驱逐.但是,这是至少一个数量多么慢的顺序Key-Lookup中LRU-LinkedHashmap.get()会给我.
如果一个元素在缓存中,我们使用缓存来获得快速查找,如果查找很慢,则缓存它没有意义.我也尝试了getAllPresent(a),asMap()但它提供了相同的性能.
库版本是:guava-11.0.1.jar
LoadingCache定义如下:
LoadingCache<TileKey, Bitmap> tiles = CacheBuilder.newBuilder().maximumSize(100).build(new CacheLoader<TileKey,Bitmap>() {
@Override
public Bitmap load(TileKey tileKey) {
System.out.println("Loading in " + Thread.currentThread().getName() + " "
+ tileKey.x + "-" + tileKey.y);
final File[][] tileFiles = surfaceState.mapFile.getBuilding()
.getFloors().get(tileKey.floorid)
.getBackground(tileKey.zoomid).getTileFiles();
String tilePath = tileFiles[tileKey.y][tileKey.x].getAbsolutePath();
Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
return BitmapFactory.decodeFile(tilePath, options);
}
});
Run Code Online (Sandbox Code Playgroud)
我的问题是:
该EventQueuejavadoc的规定,则要求入队的事件顺序,为了调度.
难道纠正Runnableš排队,以EventQueue.invokeLater保证后续的用户事件(例如,之前被分派MouseEvent)?换句话说Runnable,如果用户事件发生之后,可以在排队之前执行事件处理程序EventQueue.invokeLater.
谢谢!
我正在使用Angulartics和Angulartics Google Analytics [1]来跟踪角度页面中的用户流.跟踪事件运作良好.跟踪网页浏览也是自动且有效的.但是,在Google Analytics信息中心中,我无法看到网址的锚点部分.
跟踪请求如下所示:
https://www.google-analytics.com/collect?
v=1&_v=j51&a=333486222&t=screenview&_s=7&
cd=%2Findex.html%23%2Fsign-in&
dl=http%3A%2F%2Flocalhost%2Findex.html&
ul=de&de=UTF-8&
dt=Treat&
sd=24-bit&sr=1918x941&
vp=1918x845&je=0&
fl=25.0%20r0&an=Treats&_u=SACAAMABO~&jid=&
gjid=&cid=1883662174.1492999789&
uid=Mark-user&tid=UA-9675XXXX-1&z=124537179
Run Code Online (Sandbox Code Playgroud)
请注意如何cd=%2Findex.html%23%2Fsign-in包含#sign-inURI的一部分,但重要的dl=http%3A%2F%2Flocalhost%2Findex.html不是.
我的app.js看起来像这样:
... }).config(function ($analyticsProvider) {
$analyticsProvider.firstPageview(true); /*Records pages that don't use $state or $route*/
$analyticsProvider.withAutoBase(true); /*Records full path*/
$analyticsProvider.virtualPageviews(true);
});
;
Run Code Online (Sandbox Code Playgroud)
如何跟踪完整的URI,包括使用Angulartics进行综合浏览的锚点,而无需使用手动触发器代码?
[1] https://github.com/angulartics/angulartics-google-analytics
[2] https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#location