在不同的编程语言之间进行桥接

时间:2013-03-25 07:43:56

标签: java c++ python c thrift

这更像是一个设计问题。

我计划编写一些实现CPU密集型算法的Web服务。我试图解决的问题是 - 更高级的语言,如python,perl或java,使编写Web服务变得容易。虽然C,C ++等低级语言可以微调代码的性能。

所以我在看我能做什么来桥接两种语言。以下是我提出的选项:

语言特定绑定

使用像perl-xs或python的ctypes / loadlibrary或java的JNI之类的东西。最重要的是我可以编写可以在同一进程中执行的扩展。将本机语言类型转换为C并返回后,开销很小。

实施单独的守护程序

使用类似thrift / avro的东西,并有一个运行C / C ++代码的单独守护进程。好处是,它与高级语言松散耦合。我可以快速替换高级语言。缺点是序列化和本地unix域套接字的开销可能高于在同一地址空间中执行代码(由前一个选项提供)。

你们有什么想法?

4 个答案:

答案 0 :(得分:1)

如果您的C / C ++代码已经存在,最好的办法是将其作为服务发布,其API与您已有的功能相匹配。然后,您可以使用您选择的语言编写新服务,匹配您需要的API,并且可以调用C / C ++服务。

如果您的C / C ++代码尚不存在,并且您将设置为使用更高级别的语言(如Java或C#)创建大部分代码,请考虑最初使用该语言实现性能关键部分。只有在分析显示特定的性能问题之后,并且在您耗尽了语言中最基本的优化技术之后,例如避免在最热循环内进行分配,您应该考虑使用已证明使用最多循环的位重写为另一种语言胶水,如JNI。

换句话说,在手头有数字之前不要进行优化。还有一个根本原因,你不能从C ++中挤出(几乎)与Java相同的性能水平,并且有足够的尝试。你有一个真正的机会最终得到一个比你期望的更简单的架构。

答案 1 :(得分:0)

根据您自己的推理,用更高级别的语言实现守护进程不是更好吗?这让我们回到第1步:如何从更高级别的语言提供对C代码的访问。

如果您决定直接在C中编写守护程序,那么最重要的是您必须维护所有与您提供的核心功能无关的服务器代码。这是调试的另一件事。因为它是一项服务,所以它还需要保持安全并且没有安全漏洞。

但正如您所提到的,在C中编写特定语言的扩展名意味着您基本上坚持使用该语言。正确?

不一定。让我向您介绍SWIG:http://www.swig.org/

使用SWIG,可以大大简化在C代码和目标语言之间编写接口桥的工作。事实上,在我工作的地方,我们甚至只使用它与Java接口,永远不会使用它的多语言支持。它是一个工具,可以根据您提供的接口文件为您自动生成样板代码。

是的,接口文件是另一种要学习的语法。是的它确实有它的局限性。但它的效果非常好。

使用SWIG的一大优势是您的库只是一个常规的C / C ++库。这往往简化和澄清代码。这也意味着如果需要,您还可以在C / C ++项目中直接使用库。

答案 2 :(得分:0)

看一下Mongrel,然后用C ++编写Web服务和高性能代码。

答案 3 :(得分:0)

“序列化和本地UNIX域套接字的开销”不是问题。假设守护进程和Web服务代码之间交换的数据大小(或小于)通过网络从Web服务发送到客户端的数据大小(或小于),网络可能最终成为您的瓶颈,并且开销几乎无法衡量。

这是一个测试在UNIX套接字上传输1GB的脚本(需要netcat-openbsd软件包和bash,支持大量数据,从Custom format for time command借用时间码):

#!/bin/bash
rm -f hello.sock
nc -l -U hello.sock | wc -c &
sleep 1
T="$(date +%s%N)"
dd if=/dev/zero bs=1048576 count=1024 | nc -U hello.sock
T="$(($(date +%s%N)-T))"
echo "$T nanoseconds / GB"
rm -f hello.sock

在我的英特尔酷睿i7系统上,我得到1664042362纳秒/ GB。转换为gbit / s:

(1 GB / 1664042362 ns) * (1000000000 ns / s) * (8 gbit / 1 GB) ~ 4.8 gbit / s

在我的系统上,此基准测试完全使用2个内核(通过修改程序以输出几GB并查看vmstat来确定)。因此,如果您的gbit / s中的Internet连接是K,并且您有N个内核,那么当网络完全加载时,IPC使用的CPU百分比将是:

(K / 4.8) * (2 / N)

如果您使用至少四个核心,则Web服务客户端的带宽为100mbps或更慢,通过IPC传输的数据大小与从Web服务传输到客户端的数据大小相同或更小,通过IPC开销烧掉你的CPU的1%或更少。