我指的是此讨论。我从未用 C 或 C++ 编写过任何代码。我没有任何CS背景。然而,我作为 Java 开发人员已经工作了 5 年,现在我决定学习更多有关 CS 的知识并进行一些补习。
I am referring to this discussion. I have never written any code in C or in C++ . I do not have any CS background. However I have been working as Java developer for 5 years and now I have decided to learn more about CS and do some catching up.
发布评论
评论(10)
执行给定的代码片段时,每当调用标准函数时,执行时间都会比转储该函数中包含的代码稍长。每次转储函数中包含的整个代码在另一端是无法维护的,因为这显然会导致代码重复的混乱。
内联通过让您将函数声明为内联(至少在 C++ 中)来解决性能和可维护性问题,这样当您调用该函数时 - 而不是让您的应用程序跳转在运行时左右 - 每次调用给定函数时,都会在编译时注入内联函数中的代码。
这样做的缺点是 - 如果您内联多次调用的大函数 - 程序的大小可能会显着增加(最佳实践建议确实只在小函数上这样做)。
When executing a given piece of code, whenever you call a standard function the execution time is slightly higher than dumping there the code contained into that function. Dumping every time the whole code contained in a function is on the other end unmainteinable because it obviously leads to a whole mess of duplication of code.
Inlining solves the performance and maintainability issue by letting you declare the function as inline (at least in C++), so that when you call that function - instead of having your app jumping around at runtime - the code in the inline function is injected at compile time every time that given function is called.
Downside of this is that - if you inline big functions which you call a lot of times - the size of your program may significantly increase (best practices suggest to do it only on small functions indeed).
http://en.wikipedia.org/wiki/Inlined
在计算、内联扩展或内联中,是一种编译器优化,它将函数调用站点替换为被调用者的主体。这种优化可以改善运行时的时间和空间使用,但可能会增加最终程序的大小。
http://en.wikipedia.org/wiki/Inlining
In computing, inline expansion, or inlining, is a compiler optimization that replaces a function call site with the body of the callee. This optimization may improve time and space usage at runtime, at the possible cost of increasing the size of the final program.
作为 Java 开发人员,您通常不必担心方法内联。 Java 的即时编译器可以并且将会在大多数有意义的地方自动执行此操作。
像 eclipse 这样的 IDE 可以有一个功能,允许您在源代码级别内联方法 - 永远为了性能而这样做,只是为了代码可读性(例如,当您意识到该方法只是调用另一个方法而不需要添加任何有用的东西)。
As a Java developer, you generally don't have to worry about method inlining. Java's Just-in-time compiler can and will do it automatically in most places where it makes sense.
IDEs like eclipse can have a feature that allows you to inline methods at the source code level - never do this for performance, only for code readability (e.g. when you realize that the method just calls one other method without adding anything useful itself).
Norman Maurer 在他的博客中进行了解释< /a> 类似的 JVM 和 JIT 内联功能
还带有警告
并且您可以在内联Java代码中找到一个非常简单的内联Java代码示例。 javaworld.com/article/2078635/enterprise-middleware/jvm-performance-optimization-part-2-compilers.html?page=2" rel="noreferrer">Eva Andreasson 的 Java World Post 。您可以在下面找到帖子的相关部分。
清单 3. 调用方方法
清单 4. 被调用方法
清单 5. 内联方法
清单 6. 内联后,可以应用更多优化
Norman Maurer explains at his blog JVM and JIT inline functionality like that
Also with a warning
And you can find a very simple code example for inlining a Java code at Eva Andreasson's Java World Post. You can find the related part of post at below.
Listing 3. Caller method
Listing 4. Called method
Listing 5. Inlined method
Listing 6. After inlining, more optimizations can be applied
正如其他答案中已经提到的,内联是有成本的。通常这被认为很小,但是当实际测量时,您可能会感到惊讶并发现它可能比您获得的要大(因此 其他人说的是正确的:除非您进行了测量,否则不要优化)。
值得注意的是,在 Linux 内核中,他们前段时间开始取消内联原本内联的函数,因为成本太高(较大的函数消耗更多的 cpu 内存缓存,由此产生的缓存未命中比仅仅调用该函数的成本更高)旨在内联)。请参阅 doc/Documentation/process/ 中的“第 15 章:内联疾病” coding-style.rst 了解更多详细信息。
As already mentioned in other answers, inlining comes with a cost. Usually this is considered small, however when actually measuring you might be surprised and learn that it might be greater than what you gain (so what other people say is true: do not optimize unless you have measured).
It is worth noting that in the Linux kernel they started un-inlining originally inlined functions some time ago because the cost was too high (larger functions consumed more of the cpu memory cache, and the resulting cache misses were more expensive than just calling the function that were intended to be inlined). See "Chapter 15: The inline disease" in doc/Documentation/process/coding-style.rst for more details.
编译器优化答案是正确的。不过,还有另一种用法 - 在重构中,内联是指用主体替换方法调用该方法,然后删除该方法。请参阅内联方法。还有类似的重构,例如Inline Class。
编辑:请注意,重构是手动或使用工具完成的;无论哪种情况,都涉及更改源代码。
The compiler optimization answers are correct. There is another usage, though - in refactoring, inlining refers to replacing a method call with the body of the method and then removing the method. See Inline Method. There are similar refactorings, such as Inline Class.
EDIT: Note that refactoring is done manually or with a tool; in either case it involves changing the source code.
基本上,在 C/C++ 中,编译器可以内联函数,这意味着代码将被添加到调用函数的块中,而不是进行函数调用来执行该操作,因此就好像它从未是一个单独的函数一样函数调用。
这将进行更详细的介绍:
http://www.codersource.net/cpp_tutorial_inline_functions.html
Basically, in C/C++, the compiler can inline functions, which means that rather than making a function call to do that operation, the code will be added to the calling function's block, so it will be as though it had never been a separate function call.
This will go into more detail:
http://www.codersource.net/cpp_tutorial_inline_functions.html
内联是指编译时优化,其中一小段代码将被注入到调用函数中,而不需要单独调用。
Inlining refers to compile-time optimization where a small function of code will be injected into the calling function rather than require a separate call.
在那次讨论中,Jon Skeet 提到了客户端 jvm(热点)v 服务器 jvm,如果允许 JIT(即时)编译器带来基于时间的增强,则可以在运行时获得性能改进。这就是 Java 中的“工作原理”。
最初,编译器将“内联”不从许多地方调用的小段代码,这意味着所谓的单例将直接放置在指令指针代码路径中,执行函数分支和返回会消耗更多的处理器能力 。
如今,单例是多页讨论的主题,而循环展开以及内联之类的内容在某种程度上已从其原始上下文中删除 您可以阅读 Dov Bulka 关于此事的非常有见地的著作,以了解 C/C++ 对此事的看法。对于 Java,研究 java.util 中丰富的库比研究内联和深层编译器问题更能满足您的需求 - 您可能会沉迷于数据结构上根深蒂固的内部战争,这掩盖了对 16 位代码的调用,并且你的学习曲线永无止境。
你可以在Java中做instanceof,它类似于一个vf-table(请不要热心人),但把它想象成你一直在用强类型语言编写 - 现在将用一种字符串可以轻松失控的语言编写它没有业务的地方。我最近尝试编写用 Java 构建图像的代码,这是通过 C 代码实现的。我很快发现自己正在查看 oxr 表以进行强加密 - 这与我正在编写的代码无关。
如何用 C/C++ 编写一个字符串类,该类具有一个用于 32 字节以下字符串的小缓冲区并捕获指针,以便它们仅对字符串进行操作?
不是想取笑你或任何东西,它只是一个非常好的起点,而不是内联和编译器科学。
In that discussion, Jon Skeet mentions Client jvm (hotspot) v Server jvm with the performance improvements available at run-time if the JIT ( just-in-time ) compiler is allowed to bring time-based enhancements. That is "how it's done" in Java.
Originally, small sections of code that were not called from many places would be "inlined" by the compiler, meaning that what was called a singleton would be placed directly in the instruction pointer code path, doing a function branch and return costs more processor power than just unrolling to loop or function call and placing the instructions "right there"
Today, Singleton is the subject of multi-page discussions and loop-unrolling as well as something like inlining are somewhat removed from their original context(s). You can read Dov Bulka's very informed work on the matter to get the C/C++ take on the matter. For Java, study of it's rich lib's in java.util would better serve your needs than study of inlining and deep compiler issues - you can get hung on entrenched embattled intramural warfare on data structures, which gloss over calls into 16-bit code, and go no end on your learning curve.
You can do instanceof in Java, that resembles a vf-table ( no heat folks, please ) but think of it as you have been writing in a strongly typed language - and now will be writing in a language where string can runaway easily poking around where it has no business. I recently tried to write code that constructed an Image in Java, doing that from C code. I soon found myself looking at the oxr table for strong encryption - that has nothing to do with the code I was writing.
How would you write a string class in C/C++ that has a small buffer for strings under 32 bytes and traps pointers so that they only operate on the string?
Not trying to tease you or anything, it's just a really good place to start rather than inlining and compiler science.
内联函数通常用在 C++ 头文件中,而不是 Java 中。 C++ 头文件通常不包含实现的代码,并被视为同名 cpp 文件的接口,该文件通常包含实现的代码。在头文件中包含内联函数是合法的,通常是小型轻量级函数。内联函数确实是有代价的,因此它们不应该是大型内存密集型操作。对于小型例程,对性能的影响很小,并且更多地使用它们是为了方便。
Inline functions are used typically in C++ header files not Java. A C++ header file usually does not contain implemented code and is considered an interface to the cpp file of the same name, which does usually contain the implemented code. It is legal to include an inline function in a header file, usually a small lightweight function. Inline functions do come at a cost, so they should not be large memory-intensive operations. For small routines the performance hit is minimal and they are more used for convenience.