如何编写更高效的代码

发布于 2024-09-16 06:57:29 字数 844 浏览 10 评论 0原文

世纪问题?我基本上想知道如果我将此代码编写为几个不同的变量或使用小数组,哪个会更有效。

int x = 34;
int y = 28;
int z = 293;

vs

double coordinate[3] = {34, 28, 293};

我有一个坐标结构,我将按以下方式使用它:

typedef struct coordinates_t {
    double x = 0.0;
    double y = 0.0;
    double z = 0.0;

} coordinates;


typedef struct car_t {
    coordinates start; // car starting point
    coordinates location; // car current Location
    coordinates targCarVector; // Vector to car from target
    coordinates altitude; // Altitude of car
    coordinates distance; // Distance from car start to current position
} car;

我需要做类似的事情:

distance = car1.location - car1.start;

如果我不使用数组,我将不得不有很多代码行,但是如果我使用数组我将不得不使用循环。数组和循环是否更占用内存/CPU?我基本上想看看哪种是编写这段代码最有效的方法。

谢谢, 半羊

Question of the century? I basically want to know which would be more efficient if I wrote this code as several different variables or if I used small arrays.

int x = 34;
int y = 28;
int z = 293;

vs

double coordinate[3] = {34, 28, 293};

I have a coordinate struct which I will use in the following way:

typedef struct coordinates_t {
    double x = 0.0;
    double y = 0.0;
    double z = 0.0;

} coordinates;


typedef struct car_t {
    coordinates start; // car starting point
    coordinates location; // car current Location
    coordinates targCarVector; // Vector to car from target
    coordinates altitude; // Altitude of car
    coordinates distance; // Distance from car start to current position
} car;

I'll need to do things like:

distance = car1.location - car1.start;

If I don't use an array I'll have to have a lot of lines of code, but if I use an array I'll have to use loops. Are arrays and loops more memory/cpu intensive? I am basically trying to see which is the most efficient way of writing this code.

Thanks,
DemiSheep

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

深白境迁sunset 2024-09-23 06:57:30

第一个问题是:您想优化它吗?很可能您不想。至少如果你“总是在编码时就好像最终维护你代码的人是一个知道你住在哪里的暴力精神病患者”。 可读性、意图清晰性和可维护性始终是第一位的。

第二个问题是:是否值得优化?根据唐纳德·高德纳 (Donald Knuth) 的说法,97% 的情况并非如此 - 而且您不会质疑高德纳 (Knuth),不是吗?另一个常见的经验法则是 80/20 规则,即 80% 的执行时间花在 20% 的代码上。 如果要进行优化,请首先进行分析以了解要优化的位置。如果你猜,那你就错了。

第三个问题是:你能优化它吗?不,你不能,至少不能这么容易。 您认为您比数十年来编写您的编译器的数百名程序员更聪明吗?事实并非如此。如果您的算法和数据结构的实际实现可以优化,您可以假设您的编译器可以自行做到这一点。编译器可以进行循环展开、指令重新排序、组合具有非重叠生命周期的变量、结构布局优化等等 - 在这个时代,它在大多数情况下甚至比大多数汇编程序员更好。即使有一点潜力,你最好专注于实现更好的算法。没有编译器可以将 O(n^2) 转换为 O(n log n),但也许聪明的计算机科学家做到了,并且您可以实现他的算法以获得比任何微优化所能产生的更好的性能。

The first question is: Do you want to optimize it? Most probably, you don't want to. At least not if you "always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." Readability, clarity of intent and maintainability always come first.

The second question is: Is it worth optimizing? In 97% it isn't, according to Donald Knuth - and you don't question Knuth, do you? Another common rule-of-thumb is the 80/20 rule, i.e. 80% of execution time is spent in 20% of the code. If you optimize at all, first profile to know where to optimize. If you guess, you're wrong. Period.

The third question is: CAN you optimize it? No you can't, at least not this easily. You think you're smarter than the hundreds of programmers who wrote your compiler over many decades? You aren't. If the actual implementation of your algorithm and data structures can be optimized, you can assume your compiler can do that on its own. The compiler can do loop unrolling, instruction reordering, combining variables with non-overlapping lifetime, struct layout optimization, and much much more - and in this era, it's even better than most assembly programmers in most cases. And even if there's a bit of potential, you better focus on implementing a better algorithm. No compiler can turn O(n^2) into O(n log n), but maybe a smart computer scientist did it and you can implement his algorithm to get much better performance than any microoptimization can yield.

青萝楚歌 2024-09-23 06:57:30

您必须针对您想要执行此操作的每个平台进行衡量。

但我认为这根本不会产生任何明显的差异。 (也许除了一些嵌入式平台。这是我不太了解的领域。)所以首先以最容易阅读和理解的方式编写代码。然后测量您的代码是否变慢,并使用分析器找到程序花费大量时间的确切位置。然后尝试改进这些,在每次更改后进行测量,看看它产生了哪些效果。

提高易于理解的代码库的速度比理解充满过早和不必要的“优化”的代码库要容易得多。

可衡量的运行时改进通常来自算法更改,而不是来自像这样的微观优化。花时间尝试寻找更好的算法。

You would have to measure for each platform you want to do this one.

However I don't think this would make any noticeable difference at all. (Maybe except for some embedded platforms. That's an area I don't know much about.) So first write the code in the way that's easiest to read and understand. Then measure whether your code is to slow, and use a profiler to find the exact spots where the program spends to much time. Then try to improve those, measuring after each change to see which effect it had.

Improving the speed of an easy to understand codebase is much easier than understanding a codebase that's riddled with premature and unneeded "optimization".

Measurable run-time improvements usually come from algorithmic changes, not from micro-optimizations like this one. Spend your time trying to find better algorithms.

好菇凉咱不稀罕他 2024-09-23 06:57:30

如果您确实想对此进行微优化,请使用 CPU 的 SIMD 指令功能。如果您使用的是 x86 平台,则可以使用 MMXSSE 指令进行向量算术,而不是单独添加坐标的每个部分(如果没有,您的编译器可能不会生成这些指令)特殊的命令行开关或内联汇编)。与在单个变量和数组之间切换相比,这可能会带来更大的加速。我说“可能”是因为如果不尝试两种方法并测量执行时间,就无法确定。

If you really want to micro-optimize this, use the SIMD instruction capabilities of your CPU. If you are using an x86 platform, you can use MMX or SSE instructions to do vector arithmetic instead of adding each part of the coordinate individually (your compiler may not generate these without special command-line switches or inline assembly). This will probably amount to a larger speedup than switching between individual variables and an array. I say "probably" because there is no way to tell for sure without trying it both ways and measuring the execution time.

城歌 2024-09-23 06:57:30

使用数组,使用 -funroll-loops 进行编译。您可以获得两者的好处。

Use an array, compile with -funroll-loops. You get the benefits of both.

知你几分 2024-09-23 06:57:30

如果编译器认为有帮助,他们可以“展开”循环。因此,编译器可能会悄悄地将以下代码替换

for (i = 0; i < 3; ++i) {
    c[i] = a[i] - b[i];
}

c[0] = a[0] - b[0];
c[1] = a[1] - b[1];
c[2] = a[2] - b[2];

:编译器将根据所涉及操作的成本和您提供的优化标志,对是否值得这样做进行最佳猜测。

对于“哪一个更快?”没有简单的答案,但如果有的话,您可以确定,通过最大程度的优化,您的编译器会使用它。

Compilers can "unroll" loops if they think it will help. So the compiler might quietly replace the following code:

for (i = 0; i < 3; ++i) {
    c[i] = a[i] - b[i];
}

with:

c[0] = a[0] - b[0];
c[1] = a[1] - b[1];
c[2] = a[2] - b[2];

The compiler will take its best guess as to whether it's worth doing this, taking into account the costs of the operations involved and the optimisation flags you provide.

There is no simple answer to "which one will be faster?", but if there was you can be sure that with maximum optimisation, your compiler would use it.

琉璃繁缕 2024-09-23 06:57:30

如有疑问,请为每个项目编写原型并对其进行分析。对于这个级别的东西,我预测任何性能差异都会被忽略。使用有意义并且最清楚地传达设计意图的内容。

按照重要性的降序排列,代码必须是

  1. 正确的——如果代码给出了错误的答案或做了错误的事情,那么代码的速度有多快并不重要;
  2. 可维护——如果你不能修复或修改它来适应新的需求,那么你的代码有多快也没有意义;
  3. 健壮——如果你的代码在第一个不可靠的输入提示上进行核心转储,那么它的速度有多快并不重要;

此后您可以开始担心性能。

When in doubt, code up prototypes for each and profile them. For stuff at this level, I will predict that any differences in performance will be down in the noise. Use what makes sense and most clearly conveys the intent of the design.

In descending order of importance, code must be

  1. Correct - it doesn't matter how fast your code is if it gives you the wrong answer or does the wrong thing;
  2. Maintainable - it doesn't matter how fast your code is if you can't fix it or modify it to accomodate new requirements;
  3. Robust - it doesn't matter how fast your code is if it core dumps on the first hint of dodgy input;

Somewhere after this you can start worrying about performance.

忘年祭陌 2024-09-23 06:57:30

本世纪的答案是

不要本末倒置。

换句话说,首先是配置文件。

每个人都“知道”这一点,但是关于 SO 的一大类问题的形式是“X 或 Y 哪个更快?”

这会引发猜测,当您关心性能时,猜测没有多大价值,因为如果您遇到性能问题,它可能完全出在其他地方。

The answer of the century is

Don't put the cart before the horse.

In other words, profile first.

Everybody "knows" this, but a large category of questions on SO are of the form "Which is faster, X or Y?"

This elicits guesses, and when you're concerned about performance, guesses aren't worth much, because if you have a performance problem, it is probably somewhere else entirely.

乖乖哒 2024-09-23 06:57:30

我通常不担心效率......

它加快速度的一个地方是如果我搜索一个数值
假设我想查找帐号“188335344”,它会比搜索字母字符快得多。当搜索非数字值时,搜索必须将每行文本切换为大写。对于数字来说并非如此。

实际上快了很多。

任何需要用户输入的事情都可能效率极低,而且毫无意义。

我确实在每次搜索结束时显示经过的时间。因此,可以将较旧的代码与最近的更改进行比较。

I usually don't worry about efficiency...

One place where it speeds things up is if I do a search for a numeric value
Say I want to find an account number "188335344" it will happen far faster than searching for alpha characters. The search must switch each line of text to upper case as it searches for non numeric values. Not so for numbers.

Quite a bit faster actually.

Anything that requires user input can be extremely inefficient and it won't matter an iota.

I do display the elapsed time at the end of each search. So older code can be compared against more recent changes.

旧情勿念 2024-09-23 06:57:30

与往常一样,您需要分析您的代码才能确定。

话虽如此,我建议使用数组和循环 - 你的代码应该更简洁/可维护,并且编译器应该能够很好地优化/展开所有小的常量大小的循环,这实际上是如果您对每个向量使用 x,y,z 坐标,那么您将手动完成。

在一个完全不相关的注释中,我看到你的车有高度。这是飞行汽车吗?如果是这样,那么肯定为这个很酷的应用程序+1。

As always, you'll need to profile your code to be sure.

Having said that, I'd suggest going for an array and loops - you code should be more concise/maintainable and the compiler should be able to do a good job at optimising out / unrolling all the little constant-sized loops which is effectively what you would be doing by hand if you used x,y,z co-ordinates for every vector.

On a completely unrelated note I see you car has altitude. Is it a flying car? If so then definitely +1 for the cool application.

浮华 2024-09-23 06:57:30

采用更正确的方法 - 使用循环和数组 - 两者都不会导致更多的内存使用(更少的使用,因为所有这些 car1、car2、car3... 指令所需的内存会更多) - 和 CPU在使用方面,您会看到最微小的差异。

Go for the more correct way - which would be using loops and arrays - neither of which result in more memory usage (less usage, as the memory required by all those car1, car2, car3... instructions will be more) - and CPU usage-wise you're look at the tiniest of differences.

嗫嚅 2024-09-23 06:57:30

请分析您的代码并找出效率低下的主要问题是什么。效率可以通过代码的运行时执行来衡量。

一些这样做的工具可以作为开源工具使用,例如 gprof

Please profile your code and find out what's the main problem for the inefficiency. Efficiency can be measured by runtime execution of code.

Some tools to do so are available as opensource like gprof.

我还不会笑 2024-09-23 06:57:29

效率比可维护性和可读性更重要吗?答案是否定的。即使您有一个对时间要求严格的应用程序,您也会将 90% 的时间花在不到 10% 的代码上,因此只需尽可能高效地编码这 10% 的代码。

如果您还没有测量并找出哪 10% 是罪魁祸首,那么您几乎肯定会优化一开始就不需要太多运行时间的代码。这是浪费时间。

Is efficiency more important that maintainability and readability? The answer is no. Even if you have a time-critical application, you will spend 90% of the time in under 10% of the code, and so only that 10% needs to be coded as efficiently as possible.

If you haven't measured and found which 10% is the culprit, you almost certainly will be optimising code which doesn't take much runtime in the first place. This is a waste of time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文