我试试“http://thrift-tutorial.readthedocs.org/en/latest/usage-example.html”的例子。这个例子只计算两个数的乘积。服务器:Java,客户端:Python。
如果我尝试通过节俭获得产品3000次,则经过的时间约为4.8秒。 如果我在python中创建一个简单的函数(乘法)并直接调用3000次,则经过的时间约为0.007秒(快686倍)。
那我怎样才能提高性能呢?我想构建一个应用程序并将其分成一些子应用程序。它们可以用多种语言实现,并且它们将通过节俭相互通信,但是如果这样的性能不佳,我应该考虑将它们组合到单独的应用程序中吗?
App-A (Java) App-B (Python)
| |
|------------ App-C (C++) --------|
或
App-A+C (Java) App-B+C (Python)
(implement C in Java) (implement C in Python)
答案 0 :(得分:2)
您可以将两个关键优化设置为目标:
你在问题中描述的是一个“聊天协议”的极端情况。网络具有延迟(延迟)。如果在开始下一次计算之前等待每个结果,则大部分时间都花在等待网络传输上,而不是用于实际计算。通过在接收第一个结果之前发送另一个计算,可以显着提高吞吐量。
所以最简单的方法是允许重叠请求。第二对值的乘积不依赖于第一个结果,因此不要等待第一个结果到达。
当您处理本地IPC时,这并没有多大帮助。通信的成本不是延迟,它是消息处理和线程同步,取决于请求的数量,而不是订单。
更大收益的更大变化是使每个请求代表一个复杂的算法。例如,不是远程调用两个数字的乘法,而是尝试远程调用整个过滤操作,其中参数是整个数据向量或矩阵,服务器将执行FFT,多次,逆FFT,缩放,然后传回结果。这满足了两个原始目标:所有可用数据一起发送,而不是单独发送,减少等待的时间。并且总网络流量减少,因为不需要交换中间结果。
最后一种方法是将所有三种语言的代码链接到一个进程中,以便数据访问和函数调用是直接的。许多语言允许构建导出普通“C”函数和数据的对象。
此外,.NET等虚拟机运行可以通过编译不同源语言生成的中间语言。使用.NET,您可以使用C#(类似Java),C ++ / CLI(支持完整的C ++,以及处理.NET数据的扩展)和IronPython,它们涵盖了您的问题图。加上F#,JavaScript,Ruby变种,等等。 Java虚拟机应该是特定于语言的,但是人们已经编写了Clojure和其他编译为字节码的语言。
虚拟机技术的优势在于它可以实现一些跨语言优化(.NET JIT可以进行跨模块内联)。缺点是您的性能由JIT优化决定,JIT优化通常是最低的共同标准。 C ++ / CLI实际上非常适合弥合这个差距,因为它支持完全优化的本机代码(包括SIMD),.NET中间语言(MSIL),以及它们之间进行通信的最低开销层(C ++“It Just Works”interop )。
但是你可以在Java VM上完成同样的事情,通过使用JNI连接完全优化的C ++代码,使用SIMD进行强烈的数字运算。
答案 1 :(得分:1)
您的比较基于不正确的假设。假设是,跨进程调用(至少)与进程内调用一样快,这根本不是真的。
这是着名的8 network fallacies originated by Peter Deutsch,后来extended by others之一,不仅适用于网络,也适用于单机上的IPC:与您的想法相反, {{3 }} 即可。
根据您的有限信息我可以告诉您,每次IPC往返1.5毫秒对我来说听起来并不是那么糟糕。