Python代码一键转Jar包及Java调用Python新姿势

  

需求背景

  

进击的Python

  

随着人工智能的兴起,Python这门曾经小众的编程语言可谓是焕发了第二春。

  


   Python代码一键转Jar包及Java调用Python新姿势

  

以tensorflow, pytorch等为主的机器学习/深度学习的开发框架大行其道,助推了python这门曾经以爬虫见长(python粉别生气)的编程语言在TIOBE编程语言排行榜上一路披荆斩棘,坐上前三甲的宝座,仅次于Java和C, c++,将JavaScript, PHP, c#等一众劲敌斩落马下。

  


   Python代码一键转Jar包及Java调用Python新姿势”> <br/>
  <img src=

  

当然,轩辕君向来是不提倡编程语言之间的竞争对比,每一门语言都有自己的优势和劣势,有自己应用的领域。
  另一方面,TIOBE统计的数据也不能代表国内的实际情况,上面的例子只是侧面反映了Python这门语言如今的流行程度。

  

Java还是Python

  

说回咱们的需求上来,如今在不少的企业中,同时存在Python研发团队和Java研发团队,Python团队负责人工智能算法开发,而Java团队负责算法工程化,将算法能力通过工程化包装提供接口给更上层的应用使用。

  

可能大家要问了,为什么不直接用Java做AI开发呢?要弄两个团队。其实,现在包括TensorFlow在内的框架都逐渐开始支持Java平台,用Java做AI开发也不是不行(轩辕君的前同事就已经在这样做了),但限于历史原因,做人工智能开发的人本就不多,而这一些人绝大部分都是Python技术栈入坑,Python的AI开发生态已经建设的相对完善,所以造成了在很多公司中算法团队和工程化团队使用不同的语言。

  

现在该抛出本文的重要问题:Java工程化团队如何调用Python的算法能力?

  

答案基本上只有一个:Python通过Django/瓶等框架启动一个Web服务,Java中通过Restful API与之进行交互

  

上面的方式的确可以解决问题,但随之而来的就是性能问题,尤其是在用户量上升后,大量并发接口访问下,通过网络访问和Python的代码执行速度将成为拖累整个项目的瓶颈。

  

当然,不差钱的公司可以用硬件堆出性能,一个不行,那就多部署几个Python Web服务。

  

那除此之外,有没有更实惠的解决方案呢?这就是这篇文章要讨论的问题。

  

给Python加速

  

寻找方向

  

上面的性能瓶颈中,拖累执行速度的原因主要有两个:

  
      <李>通过网络访问,不如直接调用内部模块快李   <李> Python是解释执行,快不起来李   
  

众所周知,Python是一门解释型脚本语言,一般来说,在执行速度上:

  

解释型语言& lt;中间字节码语言& lt;本地编译型语言

  

自然而然,我们要努力的方向也就有两个:

  
      <李>能否不通过网络访问,直接本地调用李   <李> Python不要解释执行   
  

结合上面的两个点,我们的目标也清晰起来:

  

将Python代码转换成Java可以直接本地调用的模块

  

对于Java来说,能够本地调用的有两种:

  
      <李> Java代码包李   <李>原生代码模块李   
  

其实我们通常所说的Python指的是CPython的,也就是由C语言开发的解释器来解释执行。而除此之外,除了C语言,不少其他编程语言也能够按照Python的语言规范开发出虚拟机来解释执行Python脚本:

  
      <李> CPython: C语言编写的解释器李   <李> Jython: Java编写的解释器李   <李> IronPython: . net平台的解释器李   <李> PyPy: Python自己编写的解释器(鸡生蛋,蛋生鸡)   
  

jython # 63;

  

如果能够在JVM中直接执行Python脚本,与Java业务代码的交互自然是最简单不过。但随后的调研发现,这条路很快就被堵死了:

  
      <李>不支持Python3.0以上的语法   <李> python源码中若引用的第三方库包含C语言扩展,将无法提供支持,如numpy等李   
  

这条路行不通,那还有一条:把Python代码转换成原生代码块,Java通过JNI的接口形式调用。

  

Python→原生代码

  

整体思路

  

先将Python源代码转换成C代码,之后用GCC编译C代码为二进制模块/dll,接着进行一次Java Native接口封装,使用瓶子打包命令转换成Jar包,然后Java便可以直接调用。

Python代码一键转Jar包及Java调用Python新姿势