据说Java在性能方面比python快10倍。这也是我从基准测试中看到的。但真正降低Java的是JVM启动时间。
这是我做的一个测试:
$time xlsx2csv.py Types\ of\ ESI\ v2.doc-emb-Package-9
...
<output skipped>
real 0m0.085s
user 0m0.072s
sys 0m0.013s
$time java -jar -client /usr/local/bin/tika-app-0.7.jar -m Types\ of\ ESI\ v2.doc-emb-Package-9
real 0m2.055s
user 0m2.433s
sys 0m0.078s
相同的文件,Docx和Python中的12 KB ms XLSX嵌入文件快25倍! WTH !!
Java需要2.055秒。
我知道这完全取决于启动时间,但我需要的是我需要通过脚本调用它来解析一些我不想在python中重新发明轮子的文档。
但是,为了解析10k +文件,这是不实际的..
无论如何要加速它(我已经尝试过-client选项,它只会加速这么少(20%))。
我的另一个想法?将其作为长时间运行的守护进程运行,在本地使用UDP或Linux-ICP套接字进行通信?
答案 0 :(得分:11)
尝试Nailgun。
注意:我不会亲自使用它。
答案 1 :(得分:6)
今天刚刚学会了滴水,作为指甲枪的另一种替代品:https://github.com/flatland/drip 另请参阅此页面以获取一些常规提示:另请参阅https://github.com/jruby/jruby/wiki/Improving-startup-time
答案 2 :(得分:2)
嗯...将文档写入目录(如果它们尚未存在)并让Java程序一次性处理所有这些文档?
答案 3 :(得分:2)
将程序更改为客户端/服务器模型,其中Java部分是仅启动一次的持久性服务器,由客户端提供,告知其执行操作。客户端可以是一个小的Python脚本,告诉服务器进程要使用哪些文件。也许通过套接字或信号向您发送命令。
答案 4 :(得分:2)
我推荐您参考Matthew Gilliard({j})的主题。下面的任何代码示例均从此处直接提供。我不会提供时间示例,部分是为了使时间简短,另一部分是使您访问他的页面。 Matthew在blog post上工作,因此他对找出如何使启动时间保持较低状态非常感兴趣。
显然,有几种方法可以做到,有些也很容易。核心思想是缓存JVM的初始化周期,而不是在每次启动时都执行它。
CDS缓存JDK的确定性(依赖于硬件)启动过程。这是书中最简单,最古老的技巧(我认为是1.5),(并且不太知名)。
从Oracle
当JVM启动时,共享归档文件被映射到内存,以允许在多个JVM进程之间共享这些类的只读JVM元数据。启动时间减少了,因此节省了成本,因为还原共享档案比加载类要快。
您可以通过运行手动创建转储
⇒ java -Xshare:dump
Allocated shared space: 50577408 bytes at 0x0000000800000000
Loading classes to share ...
// ...snip ...
total : 17538717 [100.0% of total] out of 46272512 bytes [ 37.9% used]
...然后与它配合使用
java -Xshare:on HelloJava
来自mjg的博客
在CDS预先完成核心类的某些部分加载的情况下,AOT实际上实际上是将字节码编译为本机代码(ELF格式的共享对象文件),并且可以应用于任何字节码。
不在博客中,而是在他几天前发表的谈话中进行了演示。
自述文件:
Substrate VM是一个框架,它允许在封闭环境下将Java应用程序提前(AOT)编译为可执行映像或共享对象(ELF-64或64位Mach-O)。
答案 5 :(得分:0)
有很多方法可以做到这一点 - 基本上任何事情都可行,只要它在所有批处理过程中保持JVM活着。
例如,为什么不改变Java程序来循环遍历所有文件并在JVM的一次调用中处理所有文件?或者您可以在Swing中构建一个简单的GUI应用程序,并以一些可视方式运行批处理(例如,选择目标目录,然后按“Process All ...”按钮)。
或者您可以使用Clojure REPL作为编写相应Java作业执行脚本的方法....
或者您可以使用Netty之类的内容创建服务器进程,并通过该文件发送所有文件....