【问题标题】:Automatic Java to C++ conversion [duplicate]自动 Java 到 C++ 转换 [重复]
【发布时间】:2010-11-08 22:59:04
【问题描述】:

有没有人尝试过自动将 Java 转换为 C++ 以提高速度?从长远来看,这是一场维护噩梦吗? 只需阅读 Gecko 中用于生成 HTML5 解析引擎的内容即可http://ejohn.org/blog/html-5-parsing/

【问题讨论】:

    标签: java c++ code-translation


    【解决方案1】:

    一般来说,从一种语言到另一种语言的自动转换不会有任何改进。不同的语言有不同的习语会影响性能。

    最简单的例子是循环和变量创建。在 Java GC 世界中,使用 new 创建对象几乎是免费的,而且它们也很容易被遗忘。在 C++ 中,内存分配(一般来说)很昂贵:

    // Sample java code
    for ( int i = 0; i < 10000000; ++i )
    {
       String str = new String( "hi" ); // new is free, GC is almost free for young objects
    }
    

    直接转换为 C++ 会导致性能不佳(使用 TR1 shared_ptr 作为内存处理程序而不是 GC):

    for ( int i = 0; i < 10000000; ++i )
    {
       std::shared_ptr< std::string > str( new std::string( "hi" ) );
    }
    

    用 C++ 编写的等效循环是:

    for ( int i = 0; i < 10000000; ++i )
    {
       std::string str( "hi" );
    }
    

    从一种语言直接翻译到另一种语言通常以两全其美和更难维护的代码告终。

    【讨论】:

    • 所以你说不懂java或c++的人不应该使用转换器,因为它是由不懂java和c++的人写的?或者你不能在转换器中修复它,因为它必须在 c++ 中看起来完全一样?
    • @01:据我了解这篇文章:写一个好的转换器不是转换本身,而是优化或转换后的代码。我几乎不怀疑转换器会执行任何优化。这里的问题不是写转换器的人不懂java或c++,而是从垃圾收集语言到非垃圾收集语言的转换=>如果对象应该是堆栈,如果没有优化和对象使用跟踪,你就无法决定或堆分配。还有更多这样的陷阱,例如java默认使用2字节字符,C++单字节字符...
    • 所以转换器必须以妥协告终 => 这些通常并不总是最好的表现!什么时候应该将 java 方法转换为虚拟的 C++,什么时候不应该?只有当它被宣布为最终?我认为我们可以为转换器提出数以千计的此类问题,这将导致优化的转换器具有相当多的逻辑。
    【解决方案2】:

    这种转换的积极意义在于,您需要适当的面向对象设计才能从 java 切换到 C++(范式交集)。

    但是有人说,C++ 编码相比 java 代码并没有带来速度上的提升。

    【讨论】:

      【解决方案3】:

      即使这样有效,我也不确定您是否会看到速度有很大提高。 Java 的 Hotspot JIT 编译器已经很不错了。

      【讨论】:

        【解决方案4】:

        几乎不可能通过程序将 Java 的自动内存管理替换为手动内存管理。所以你很可能最终会得到一个程序,它有内存泄漏或使用垃圾收集器的 C++ 代码。但是 Java 中的垃圾收集器要依赖的东西要多得多(例如,没有指针算法、数学),因此为了安全起见,C++ 中的垃圾收集器的性能会降低。因此,您的自动转换很可能会降低性能。

        尝试手动将其移植到 C++ 或优化 Java 代码。

        【讨论】:

        • 您可以使用垃圾收集器获得 C++ 语言系统。
        • 是的,但正如我所说,C++-garbage-collector 有更多的东西需要检查。例如指针算术使事情变得更加困难。因此,C++ 垃圾收集器通常不如 Java 和 .Net 的分代垃圾收集器高效。
        • 对所有事情都使用 shared_ptr 会影响性能,并且使用保守的 GC 可能会很慢,并且会导致一些内存泄漏。
        【解决方案5】:

        这种类型的转换外壳几乎不可能带来更好的性能。通常当 JVM 工作时,它会将大部分代码转换为本机机器码。您的建议是将 Jave 代码转换为 C++ 并从那里转换为本机机器代码,即添加一个额外的阶段。 然而,在一些微不足道的情况下,由于以下事实可能会获得一些收益:

        1) 从头开始​​加载 JVM 需要一些时间。

        2) 做Jit需要一些时间,当运行一个非常短的程序时,很多时候,你可能宁愿在运行前浪费这段时间。

        3) 如果您不是在服务器模式下运行,您可能无法在 Java 上获得相同级别的机器代码。 (在服务器模式下,您将获得一流的机器代码,以及在运行时检测到的最适合您自己的 CPU 的机器代码,这通常是大多数 C/C++ 程序植入所缺乏的,此外还有机器代码在运行时优化)

        【讨论】:

          【解决方案6】:

          这些语言的使用风格如此不同,以至于盲目的转换几乎没有用处。由于使用的样式不同,智能转换器几乎无法编写。

          一些问题领域:

          • 资源分配由 Java 中的“try{} finally{}”块控制,而 C++ 使用 RAII。
          • Java 在编译时 C++ 运行时进行异常检查。
          • 异常处理方式不同。两个例外:
            • 在 Java 中(传播最后一次抛出)
            • 在 C++ 中应用程序终止。
          • Java 拥有庞大的标准库
            C++ 具有所有相同的功能,您只需要在网上找到它[这很痛苦]。
          • Java 对所有事物都使用指针。
            • 直接不假思索的转换将使您得到一个仅由 shared_ptr 对象组成的程序。

          无论如何,JIT 编译 Java 在速度上与 C++ 相当。

          【讨论】:

            【解决方案7】:

            一般而言,就此类转换器而言,不能期望它们生成可维护或高性能的代码,因为这些通常需要一个真正了解编写代码的语言的人。它们非常有用的是使移植语言变得容易。例如,任何带有 C 转换器的语言都可以在多种语言上快速实现。我在 90 年代中期使用 f2c 在 Macintosh 上运行 Fortran 例程。

            如果您用 C++ 重写代码,您可能会或可能不会获得性能改进。如果您使用自动转换器,您可能会变慢。

            【讨论】:

              猜你喜欢
              • 2016-07-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-06-10
              • 1970-01-01
              相关资源
              最近更新 更多