简体   繁体   English

计划效率

[英]Efficiency of program

我想知道,与任何编程语言中的结构化编程方法相比,采用面向对象的方法来解决问题是否会对程序效率产生影响,特别是在c ++中。

Maybe. 也许。 Maybe not. 也许不吧。

You can write efficient object-oriented code. 您可以编写有效的面向对象代码。 You can write inefficient structured code. 您可以编写效率低下的结构化代码。

It depends on the application, how well the code is written, and how heavily the code is optimized. 这取决于应用程序,代码编写的程度以及代码的优化程度。 In general, you should write code so that it has a good, clean, modular architecture and is well designed, then if you have problems with performance optimize the hot spots that are causing performance issues. 通常,您应该编写代码,使其具有良好,干净,模块化的体系结构并且设计良好,然后如果您遇到性能问题,则优化导致性能问题的热点。

Use object oriented programming where it makes sense to use it and use structured programming where it makes sense to use it. 使用面向对象的编程,使用它是有意义的,并使用结构化编程,使用它是有意义的。 You don't have to choose between one and the other: you can use both. 您不必在一个和另一个之间进行选择:您可以同时使用两者。

I remember back in the early 1990's when C++ was young there were studies done about this. 我记得在20世纪90年代早期,当C ++年轻的时候,有关于此的研究。 If I remember correctly, the guys who took (well written) C++ programs and recoded them in C got around a 15% increase in speed. 如果我没记错的话,那些接受(编写好的)C ++程序并用C语言重新编写它们的人的速度提高了大约15%。 The guys who took C programs and recoded them in C++, and modified the imperative style of C to an OO style (but same algorithms) for C++ got the same or better performance. 那些接受C程序并用C ++重新编码的人,并将C的命令式样式修改为OO风格(但相同的算法),C ++获得了相同或更好的性能。 The apparent contradiction was explained by the observation that the C programs, in being translated to an object oriented style, became better organized. 观察到C语言被转化为面向对象的风格变得更加有条理,这就解释了明显的矛盾。 Things that you did in C because it was too much code and trouble to do better could more easily be done properly in C++. 你在C中所做的事情是因为代码太多而且做得更好也很容易在C ++中正确完成。

Thinking back about this I wonder about the conclusion some. 回想一下,我对这个结论感到疑惑。 Writing a program a second time will always result in a better program, so it didn't have to be imperative to OO style that made the difference. 第二次编写程序总会产生一个更好的程序,所以它不一定是OO风格的必要条件。 Todays computer architectures are designed with hardware support for common operations done by OO programs, and compilers have gotten better at using the instructions, so I think that it is likely that whatever overhead a virtual function call had in 1992 it is far smaller today. 今天的计算机体系结构设计有对OO程序完成的常见操作的硬件支持,并且编译器在使用指令方面已经变得更好,所以我认为在1992年虚拟函数调用的任何开销都可能远远小于今天。

There doesn't have to be, if you are very careful to avoid it. 没有必要,如果你非常小心避免它。 If you just take the most straightforward approach, using dynamic allocation, virtual functions, and (especially) passing objects by value, then yes there will be inefficiency. 如果你只是采用最简单的方法,使用动态分配,虚函数和(特别是)按值传递对象,那么肯定会有效率低下。

It doesn't have to be. 它不一定是。 Algorithm is all matters. 算法是最重要的。 I agree encapsulation will slow you down little bit, but compilers are there to optimize. 我同意封装将减慢你的速度,但编译器会在那里进行优化。

You would say no if this is the question in computer science paper. 如果这是计算机科学论文中的问题,你会说不。

However in the real development environment this tends to be true if the OOP paradigm is used correctly. 然而,在真实的开发环境中,如果正确使用OOP范例,这往往是正确的。 The reason is that in real development process, we generally need to maintain our code base and that the time when OOP paradigm could help us. 原因是在实际开发过程中,我们通常需要维护我们的代码库,以及OOP范例可以帮助我们的时间。 One strong point of OOP over structured programming like C is that in OOP it is easier to make the code maintainable. 与C类结构化编程相比,OOP的一个优点是在OOP中更容易使代码可维护。 When the code is more maintainable, it means less bug and less time to fix bug and less time needed for implementing new features. 当代码更易于维护时,它意味着更少的bug,更少的时间来修复错误,减少实现新功能所需的时间。 The bottom line is then we will have more time to focus on the efficiency of the application. 最重要的是,我们将有更多时间专注于应用程序的效率。

The problem is not technical, it is psychological. 问题不是技术问题,而是心理问题。 It is in what it encourages you to do by making it easy. 它是通过简化它来鼓励你做的事情。

To make a mundane analogy, it is like a credit card. 为了做一个世俗的比喻,它就像一张信用卡。 It is much more efficient than writing checks or using cash. 它比写支票或使用现金更有效率。 If that is so, why do people get in so much trouble with credit cards? 如果是这样,为什么人们会用信用卡遇到这么多麻烦? Because they are so easy to use that they abuse them . 因为它们很容易使用,所以它们会滥用它们 It takes great discipline not to over-use a good thing. 不要过度使用好东西需要很大的纪律。

The way OO gets abused is by OO滥用的方式是

  • Creating too many "layers of abstraction" 创建太多“抽象层”

  • Creating too much redundant data structure 创建过多的冗余数据结构

  • Encouraging the use of notification-style code, attempting to maintain consistency within redundant data structures. 鼓励使用通知式代码,尝试在冗余数据结构中保持一致性。

It is better to minimize data structure, and if it must be redundant, be able to tolerate temporary inconsistency. 最好是最小化数据结构,如果它必须是冗余的,则能够容忍暂时的不一致。

ADDED: As an illustration of the kind of thing that OO encourages, here's what I see sometimes in performance tuning: Somebody sets SomeProperty = true; 补充:作为OO鼓励的事情的例证,这是我在性能调整中有时看到的:有人设置SomeProperty = true; . That sounds innocent enough, right? 这听起来很无辜,对吧? Well that can ripple to objects that contain that object, often through polymorphism that's hard to trace. 好吧,它可以波及包含该对象的对象,通常是通过难以追踪的多态性。 That can mean that some list or dictionary somewhere needs to have things added to it or removed from it. 这可能意味着某些列表或字典需要添加到其中或从中删除。 That can mean that some tree or list control needs controls added or removed or shuffled. 这可能意味着某些树或列表控件需要添加或删除或改组控件。 That can mean windows are being created or destroyed. 这可能意味着正在创建或销毁窗口。 It can also mean some things need to be changed in a database, which might not be local so there's some I/O or mutex locking to be done. 它也可能意味着需要在数据库中更改某些内容,这可能不是本地的,因此需要执行一些I / O或互斥锁定。

It can really get crazy. 它真的会变得疯狂。 But who cares? 但谁在乎? It's abstract . 这是抽象的

There could be: the OO approach tends to be closer to a decoupled approach where different modules don't go poking around inside each other. 可能有:OO方法往往更接近于解耦方法,其中不同的模块不会在彼此内部进行探索。 They are restricted to public interfaces, and there is always a potential cost in that. 它们仅限于公共接口,并且总是存在潜在的成本。 For example, calling a getter instead of just directly examining a variable; 例如,调用getter而不是直接检查变量; or calling a virtual function by default because the type of an object isn't sufficiently obvious for a direct call. 或者默认调用虚函数,因为对象的类型对于直接调用来说不够明显。

That said, there are several factors that diminish this as a useful observation. 也就是说,有几个因素可以减少这一点作为有用的观察结果。

  1. A well written structured program should have the same modularity (ie hiding implementations), and therefore incur the same costs of indirection. 编写良好的结构化程序应具有相同的模块性(即隐藏实现),因此产生相同的间接成本。 The cost of calling a function pointer in C is probably going to be very similar to the cost of calling a virtual function in C++. 在C中调用函数指针的成本可能与在C ++中调用虚函数的成本非常相似。

  2. Modern JITs, and even the use of inline methods in C++, can remove the indirection cost. 现代JIT,甚至在C ++中使用内联方法,都可以消除间接成本。

  3. The costs themselves are probably relatively small (typically just a few extra simple operations per instruction call). 成本本身可能相对较小(通常每个指令调用只需几个简单的操作)。 This will be insignificant in a program where the real work is done in tight loops. 这对于在紧密循环中完成实际工作的程序来说是微不足道的。

  4. Finally, a more modular style frees the programmer to tackle more complicated, but hopefully less complex algorithms without the peril of low level bugs. 最后,更加模块化的风格使程序员可以解决更复杂但更有希望的复杂算法,而不会产生低级错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM