不同编程语言之间的桥接
这其实是个设计方面的问题。
我打算写一些网络服务,这些服务会用到很耗CPU的算法。现在我面临的问题是:像Python、Perl或Java这样的高级语言,写网络服务很简单;而像C、C++这样的低级语言,则可以让你的代码性能更好。
所以我在想,怎样才能把这两种语言结合起来。以下是我想到的一些方法:
语言特定的绑定
可以使用像perl-xs、Python的ctypes/loadlibrary或者Java的JNI这样的工具。这样做的好处是,我可以写一些扩展,让它们在同一个进程中运行。缺点是,在不同语言之间转换数据类型时,会有一点额外的开销。
实现一个独立的守护进程
可以使用像thrift或avro这样的工具,创建一个独立的守护进程来运行C/C++代码。这样做的好处是,它和高级语言的耦合度比较低,我可以很快替换掉高级语言。缺点是,数据序列化和本地Unix域套接字的开销可能比在同一地址空间中执行代码要高(这是前一种方法的优势)。
你们觉得怎么样?
4 个回答
根据你的推理,直接用更高级的语言来实现守护进程不是更好吗?这又把我们带回第一步:如何让更高级的语言访问你的C代码。
如果你还是决定直接用C来写守护进程,最大的缺点就是你得维护所有和核心功能无关的服务器代码。这又多了一件需要调试的事情。而且因为这是个服务,它还需要保持安全,避免出现安全漏洞。
不过正如你提到的,用C为特定语言写扩展,实际上你就被限制在那种语言上,对吧?
不一定。让我给你介绍一下SWIG:http://www.swig.org/
使用SWIG,可以大大简化你C代码和目标语言之间的接口桥接工作。实际上,在我工作的地方,我们甚至只用它来和Java对接,从来不使用它的多语言支持。它是一个工具,可以根据你提供的接口文件自动生成一些基础代码。
是的,接口文件又是一种新的语法需要学习。并且它确实有一些限制。但是它的效果非常好。
使用SWIG的一个大优点是,你的库只是一个普通的C/C++库。这通常会让代码更简单、更清晰。如果你愿意,你也可以在C/C++项目中直接使用这个库。
看看这个网站 Mongrel,然后用C++来写一个网络服务和高效的代码。
如果你已经有了C/C++代码,最好的办法是把它做成一个服务,并提供一个API(应用程序接口),让其他程序可以调用你已有的功能。这样,你就可以用你喜欢的编程语言写新的服务,只要它们能和这个API对接,就可以调用C/C++的服务。
如果你还没有C/C++代码,并且打算用更高级的语言,比如Java或C#来写大部分代码,建议你一开始就把性能要求高的部分也用这些语言实现。只有在你发现某个地方的性能有问题,并且尝试了最基本的优化方法,比如避免在最频繁执行的循环中进行内存分配后,才考虑把那些消耗最多资源的部分用其他语言重写,像是使用JNI这样的工具来连接不同语言。
换句话说,在你没有数据之前,不要急着优化。其实,如果你努力的话,Java的性能也可以接近C++,没有什么根本性的原因让它们之间的性能差距那么大。你有很大的机会最终得到一个比你预想的更简单的架构。