【问题标题】:Linking languages链接语言
【发布时间】:2010-09-21 06:03:17
【问题描述】:

我早些时候问过a question,关于人工智能原型使用哪种语言。共识似乎是,如果我希望它更快,我需要使用 Java 或 C++ 之类的语言,但 Python / Perl / Ruby 对接口位有好处。

所以,这让我想到了另一个问题。将这些语言连接在一起有多容易?哪种组合效果最好?那么,如果我想要一个 Ruby CGI 类型的程序调用 C++ 或 Java AI 函数,那么容易做到吗?关于我在哪里寻找关于做那种事情的信息的任何指示?或者不同的组合会更好?

我编写 Web 应用程序的主要经验是从 C++ CGI 开始,然后转向 Java servlet(大约 10 年前),然后在远离编程很长一段时间后,我开始了一些 PHP。但是我没有使用脚本语言编写 Web 应用程序的经验,然后调用编译语言以获得速度关键位。所以欢迎任何建议!

【问题讨论】:

    标签: java c++ python ruby perl


    【解决方案1】:

    Boost.Python 提供了一种将 C++ 代码转换为 Python 模块的简单方法。它相当成熟,在我的经验中运作良好。

    比如不可避免的Hello World……

    char const* greet()
    {
      return "hello, world";
    }
    

    可以通过编写 Boost.Python 包装器向 Python 公开:

    #include <boost/python.hpp>
    
    BOOST_PYTHON_MODULE(hello_ext)
    {
      using namespace boost::python;
      def("greet", greet);
    }
    

    就是这样。我们完成了。我们现在可以将其构建为共享库。生成的 DLL 现在对 Python 可见。这是一个 Python 会话示例:

    >>> import hello_ext
    >>> print hello.greet()
    hello, world
    

    (来自 boost.org 的示例)

    【讨论】:

      【解决方案2】:

      首先,元注释:我强烈建议使用高级语言对整个事物进行编码,疯狂地进行分析,并仅在分析表明有必要时进行优化。先优化算法,再优化代码,再考虑引入重铁。当/如果您需要用较低级别的语言重新实现时,拥有最佳算法和干净的代码将使事情变得更容易。

      对于 Python,IronPython/C# 可能是最简单的优化路径。

      CPython 与 C++ 是可行的,但我发现 C 更容易处理(但不是那么容易,作为 C)。有两个工具可以解决这个问题:cython/pyrex(用于 C)和shedskin(用于 C++)。这些将 Python 编译成 C/C++,然后您就可以轻松访问 C/C++ 库了。

      我从未使用过 jython,但我听说 jython/Java 优化路径并没有那么糟糕。

      【讨论】:

        【解决方案3】:

        我同意先用 Python 等高级语言进行编码、分析,然后用 C/C++ 实现任何需要加速的代码并将其包装以用于高级语言的想法。

        作为 boost 的替代方案,我想建议 SWIG 从 C 创建 Python 可调用代码。它使用起来相当轻松,并且将为各种语言编译可调用模块。 (Python、Ruby、Java、Lua。仅举几例)来自 C 代码。

        包装过程是半自动化的,因此无需在基本 C 代码中添加新功能,从而使工作流程更加顺畅。

        【讨论】:

          【解决方案4】:

          如果您选择 Perl,则有大量资源可用于连接其他语言。

          Inline::C
          Inline::CPP
          Inline::Java

          来自Inline::C-Cookbook

          use Inline C => <<'END_C';
          
            void greet() {
              printf("Hello, world\n");
            }
          END_C
          
          greet;
          

          使用 Perl 6,使用 NativeCall 从本机库代码导入子例程变得更加容易。

          use v6.c;
          
          sub c-print ( Str() $s ){
            use NativeCall;
          
            # restrict the function to inside of this subroutine because printf is
            # vararg based, and we only handle '%s' based inputs here
          
            # it should be possible to handle more but it requires generating
            # a Signature object based on the format string and then do a
            # nativecast with that Signature, and a pointer to printf
          
            sub printf ( str, str --> int32 ) is native('libc:6') {}
          
            printf '%s', $s
          }
          
          c-print 'Hello World';
          

          这只是一个简单的示例,您可以创建一个具有指针表示的类,并让一些方法是您正在使用的库中的 C 代码。 (仅当 C 代码的第一个参数是指针时才有效,否则您必须包装它)

          如果您需要不同的 Perl 6 子例程/方法名称,您可以使用 is symbol 特征修饰符。

          还有适用于 Perl 6 的内联模块。

          【讨论】:

            【解决方案5】:

            Perl 有几种使用其他语言的方法。查看 CPAN 上的 Inline:: 系列模块。按照这个问题中其他人的建议,我会用一种动态语言(Perl、Python、Ruby 等)编写整个东西,然后优化需要它的部分。使用 Perl 和 Inline:: 您可以在 C、C++ 或 Java 中进行优化。或者您可以查看AI::Prolog,它允许您嵌入 Prolog 以进行 AI/逻辑编程。

            【讨论】:

            • Ovid 几年前告诉我,AI::PROlog 对于生产使用来说太慢了。我曾想将它用于一个项目,但他不鼓励我:)
            【解决方案6】:

            从脚本开始,然后从该脚本调用基于编译的语言可能是一种很好的方法,仅用于更高级的需求。

            例如,calling java from ruby script 效果很好。

            require "java"
            # The next line exposes Java's String as JString
            include_class("java.lang.String") { |pkg, name| "J" + name }
            s = JString.new("f")
            

            【讨论】:

              【解决方案7】:

              您可以使用一种高级语言(例如 Python 或 Ruby)构建您的程序,然后调用以低级语言编译的模块以获得您需要的性能。您可以根据所需的低级语言选择平台。

              例如,如果你想用 C++ 来做一些快速的事情,你可以只使用普通的 Python 或 Ruby 并调用用 C++ 编译的 DLL。如果您想使用 Java,您可以使用 Jython 或 Java 平台上的其他动态语言之一来调用 Java 代码,这比 C++ 路线更容易,因为您有一个通用虚拟机,因此可以直接使用 Java 对象在 Jython 或 JRuby 中。使用 Iron 语言和 C# 在 .Net 平台上也可以这样做,尽管您似乎对 C++ 和 Java 有更多经验,所以这些会是更好的选择。

              【讨论】:

                【解决方案8】:

                我有不同的看法,我很幸运地将 C++ 和 Python 集成到一些实时视频图像处理中。

                我会说您应该将语言与每个模块的任务相匹配。如果您要响应网络,请用 Python 进行,Python 可以很好地跟上网络流量。 UI:Python,人很慢,Python 非常适合在 Mac 上使用 wxPython 或 PyObjC 或 PyGTK 的 UI。如果您正在对大量数据、信号处理或图像处理进行数学运算...使用 C 或 C++ 进行单元测试,然后使用 SWIG 创建与任何更高级别语言的绑定.

                我在我的 C++ 中使用了 wxWidgets 中的图像库,这些图像库已经通过 wxPython 暴露给 Python,因此它非常强大和快速。 SCONS 是一个构建工具(如 make),它知道如何处理 swig 的 .i 文件。

                最顶层可以是 C 或 Python,如果顶层是 C 或 C++,您将拥有更多的控制权并减少打包和部署问题...但是复制 Py2EXE 或Py2App 在 Windows 或 Mac 上为您提供(或在 Linux 上冻结。)

                享受混合编程的力量! (我称以紧密耦合的方式使用多种语言为“混合”,但这只是我的一个怪癖。)

                【讨论】:

                  【解决方案9】:

                  如果问题领域很难(而且 AI 问题通常很困难),那么我会首先选择一种表达能力强或适合该领域的语言,然后再考虑加快速度。例如,Ruby 具有元编程原语(能够轻松检查和修改正在运行的程序),这使得实现某些类型的算法变得非常容易/有趣。

                  如果您以这种方式实现它,然后需要加快速度,那么您可以使用基准测试/分析来定位瓶颈并为此链接到编译语言,或者优化算法。根据我的经验,最大的性能提升来自于调整算法,而不是来自使用不同的实现语言。

                  【讨论】:

                    猜你喜欢
                    • 2022-01-20
                    • 2017-06-26
                    • 2013-06-08
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-11-16
                    相关资源
                    最近更新 更多