C++编程效率

发布于 2024-11-03 08:03:25 字数 1350 浏览 5 评论 0原文

这是我从 Microsoft Developer Network 复制的一些代码
http://msdn.microsoft.com/en- us/library/dd162487(v=VS.85).aspx

LRESULT APIENTRY WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{

**PAINTSTRUCT ps;  
HDC hdc;**

switch (message) 
{ 
    case WM_PAINT: 
        hdc = BeginPaint(hwnd, &ps); 
        TextOut(hdc, 0, 0, "Hello, Windows!", 15);
        EndPaint(hwnd, &ps); 
        return 0L; 

    // Process other messages.   
} 
} 

我可能是错的,但我认为每次编译器运行这样的语句时:

int var1  
double var2  
char var3[]  
PAINTSTRUCT ps  
HDC hdc  

计算机都会创建一个新变量。至少这是合乎逻辑的想法,因为这就是您想要创建新变量时所写的内容,对吧?

我也一直认为,如果你有这样的代码块:

for(int i = 0; i < 100; i++)
    int sum = i;

计算机将创建 100 个不同的变量,所有变量都具有相同的名称 sum 以及包含在 i 中的一些值

在上面的示例代码中,函数 WndProc 在程序过程中将被多次调用,但是函数创建的两个变量“ps”和“hdc”只会在函数执行的某些时候使用。

那么计算机是否会生成许多永远不会使用的独立的额外 PAINTSTRUCT 和 HDC 变量?
像这样在 case WM_PAINT: 之后声明“ps”和“hdc”不是至少稍微更有效吗?

case WM_PAINT:
{ 
     **PAINTSTRUCT ps;  
     HDC hdc;**

     hdc = BeginPaint(hwnd, &ps); 
     TextOut(hdc, 0, 0, "Hello, Windows!", 15);
     EndPaint(hwnd, &ps); 
 }
 return 0L; 

Here is some code that I copied from the Microsoft Developer Network
http://msdn.microsoft.com/en-us/library/dd162487(v=VS.85).aspx

LRESULT APIENTRY WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{

**PAINTSTRUCT ps;  
HDC hdc;**

switch (message) 
{ 
    case WM_PAINT: 
        hdc = BeginPaint(hwnd, &ps); 
        TextOut(hdc, 0, 0, "Hello, Windows!", 15);
        EndPaint(hwnd, &ps); 
        return 0L; 

    // Process other messages.   
} 
} 

I am probably wrong but I thought that everytime the compiler ran a statement like any one of these:

int var1  
double var2  
char var3[]  
PAINTSTRUCT ps  
HDC hdc  

the computer would create a new variable. At least that would be the logical thing to think because that is what you write when you want to create a new variable, right?

I also always thought that if you had a block of code like this:

for(int i = 0; i < 100; i++)
    int sum = i;

the computer would create 100 different variables all with the same name sum and some value that was contained in i

In the sample code above, the function WndProc will be called many many times over the course of the program, however the two variables that the function creates called "ps" and "hdc" will only be used some of the times that the function executes.

So would the computer be making lots of separate, extra PAINTSTRUCT and HDC variables that it will never use?
Would it not be at least slightly more efficiant to declare "ps" and "hdc" after case WM_PAINT: like this?

case WM_PAINT:
{ 
     **PAINTSTRUCT ps;  
     HDC hdc;**

     hdc = BeginPaint(hwnd, &ps); 
     TextOut(hdc, 0, 0, "Hello, Windows!", 15);
     EndPaint(hwnd, &ps); 
 }
 return 0L; 

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

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

发布评论

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

评论(5

挽你眉间 2024-11-10 08:03:25

我可能是错的,但我认为每次编译器运行这样的语句时:

int var1  
double var2  
char var3[]  
PAINTSTRUCT ps  
HDC hdc  

计算机将创建一个新变量。

这些变量对应于运行时的存储空间。由于它们是本地变量,因此它们可能位于堆栈上,为这些本地变量分配空间就像移动堆栈指针一样简单。这速度快得惊人。

我也一直认为,如果你有这样的代码块:
for(int i = 0; i < 100; i++)
int 总和 = i;

计算机将创建 100 个不同的变量,所有变量都具有相同的名称“sum”和“i”中包含的一些值

这里可能发生的情况是,堆栈上的相同位置将被循环的每次迭代重用。

像这样在 case WM_PAINT: 之后声明“ps”和“hdc”不是至少稍微更有效吗?

不,它们是本地变量,它们可能在堆栈上分配,并且一旦进入方法,它们的空间就会被保留,与您在代码中声明它们的位置无关。

最后,担心这里的性能充其量只是微优化。专注于代码的含义。让编译器尽可能有效地将其翻译为可执行代码。仅当您遇到的性能问题无法满足客户的预期性能要求时,您才应该开始担心。

I am probably wrong but i thought that everytime the compiler ran a statement like any one of these:

int var1  
double var2  
char var3[]  
PAINTSTRUCT ps  
HDC hdc  

the computer would create a new variable.

These variables correspond to storage space at runtime. As they are locals, they likely live on the stack and allocating space for these locals is as simple as moving the stack pointer. This is blazingly fast.

i also always thought that if you had a block of code like this:
for(int i = 0; i < 100; i++)
int sum = i;

the computer would create 100 different variables all with the same name "sum" and some value that was contained in "i"

Likely what will happen here is that the same location on the stack will be reused for each iteration of the loop.

Would it not be at least slightly more efficiant to declare "ps" and "hdc" after case WM_PAINT: like this?

No, they are locals, they are likely allocated on the stack and their space is reserved as soon as the method is entered independent of where you declare them in the code.

Finally, worry about the performance here is a micro-optimization at best. Focus on the meaning of your code. Let the compiler translate it as effectively as it can into executable code. Only if you have performance issues that don't meet your customer's expected performance requirements should you start worrying.

宣告ˉ结束 2024-11-10 08:03:25

你是对的,计算机将声明大量局部变量,但幸运的是,这是非常有效的。首次调用函数时,编译器通常将生成局部变量的代码作为单个汇编指令输出,因此创建这些变量的开销可以忽略不计。在您的循环示例中,编译器通常不会多次创建和销毁变量。相反,它创建一次,它们在循环的每次迭代中重用该空间。换句话说,变量在每次迭代中逻辑被创建和销毁,但在生成的代码中它实际上在多个迭代之间共享。

作为更一般的规则,不要担心程序的效率,除非您有特定的理由相信您的性能低于应有的水平。您的首要任务应该是编写干净、优雅的代码,而不是第一次就优化代码,因为如果没有实际运行程序,就很难知道您的优化是否会对程序的运行时产生有用的影响。通常,您会使用分析器来确定代码的哪些位置速度较慢,然后将优化工作集中在那里。

You are correct that the computer will be declaring a lot of local variables, but fortunately this is extremely efficient. The compiler usually outputs the code to produce local variables as a single assembly instruction when the function is first called, and so the overhead of creating these variables is negligible. In your loop example, the compiler usually doesn't create and destroy the variable multiple times. Rather, it creates it once, them reuses the space on each iteration of the loop. In other words, the variable is logically being created and destroyed on each iteration, but in the generated code it actually gets shared across multiple iterations.

As a mor general rule, don't worry about the efficiency of your programs unless you have a specific reason to believe that your performance is below what it should be. Your priority should be to write clean, elegant code rather than optimized code the first time around, since without actually running the program it's very hard to know whether your optimizations will have a useful effect on the program's runtime. Usually you would use a profiler to determine what spots of the code are slow, then focus your optimization efforts there.

风筝在阴天搁浅。 2024-11-10 08:03:25

对于原始局部变量(指针、int、double、float 等)和原始数组,声明变量确实会为其“分配”空间,但实际发生的只是编译器说“我要要调用堆栈上的这个位置,请在堆栈指针下方三个字,i。”没有实际的计算发生——根本没有执行任何指令!因此,在循环内部或外部声明“sum”绝对没有任何区别!

然而,对于本地声明的类实例,情况有所不同。声明对象意味着进入块时将调用构造函数,退出块时将调用析构函数,并且确实导致指令被执行 - 所以你需要当心。

For a primitive local variable -- pointers, int, double, float, etc, -- and arrays of primitives, declaring a variable does indeed "allocate" space for it, but all that actually happens is the compiler says "I'm going to call this spot on the stack, three words below the stack pointer, i." No actual computation happens -- no instructions are executed at all! Therefore declaring "sum" inside or outside the loop makes absolutely no difference at all!

For a locally declared class instance, however, things are different. Declaring the object means that the constructor is going to be called when the block is entered, and the destructor will be called when it's exited, and that does result in instructions being executed -- so there you need to be careful.

怪异←思 2024-11-10 08:03:25

计算机将创建一个新变量

这只是表面上的事实。从技术上讲,处理器实际上所做的是将堆栈指针移动到一定的长度。如果您声明的变量没有任何构造函数,那么此操作的开销几乎为零。

那么计算机是否会生成许多永远不会使用的单独的、额外的 PAINTSTRUCT 和 HDC 变量?

不,这不是真的,一旦函数返回,为这些变量分配的所有堆栈空间都会被回收,不会浪费任何东西。

像这样在 case WM_PAINT: 之后声明“ps”和“hdc”不是至少稍微更有效吗?

不太可能。无论您将这些变量的声明放在何处,编译器都可能会在堆栈中看到这些变量的声明和分配的空间。同样,只要变量没有构造函数,情况就是如此。如果它们这样做,那么将它们放入案例中将节省对构造函数的调用。

the computer would create a new variable

This is only superficially true. Technically what the processor actually does is move the stack pointer to a certain length. If the variables you declare don't have any constructors then the overhead for this action is virtually zero.

so would the computer be making lots of separate, extra PAINTSTRUCT and HDC variables that it will never use?

No, this is not true, once the function returns all of the stack space allocated for these variables is reclaimed and nothing is wasted.

Would it not be at least slightly more efficiant to declare "ps" and "hdc" after case WM_PAINT: like this?

Not likely. The compiler is likely to see the declarations and allocated space for these variables o the stack no matter where you put the declaration for them. Again, that's true for as long as the variables don't have constructors. If they do, then putting them in the case would save the call for the constructor.

那伤。 2024-11-10 08:03:25

只要具有相同的结果,编译器就会对您的代码进行重大更改。特别是在发布(非调试)版本中。

这意味着如果您有未使用的代码、过早声明变量或有未在循环外部使用的变量,编译器可能会删除或移动它们。

/* If you never use these, the compiler will probably throw them out */
int var1;
double var2;
char var3[];
PAINTSTRUCT ps;
HDC hdc;

/* Nothing here effects other code, so the code will probably be removed */
for(int i = 0; i < 100000; ++i)
{
    int j = i * 7;
}

除非您有非常强烈的性能要求,否则您能做的最好的事情就是使代码更具可读性。如果变量在较小的范围内使用,请将其放置在那里,因为它更易于阅读,而不是因为它可能会使您的程序更快。

计算机非常擅长运行您所谈论的代码类型,您只需使用 CPU 和内存。实际上可以获得良好性能改进的地方是当您处理相对较慢的设备(例如网络)或从磁盘读取时。在这些情况下,单个字节的内存很重要。

CPU/内存优化最有意义的地方是在更复杂的算法中,或者当您处理大量数据时,例如图形或搜索算法。

这并不是说您不应该考虑优化 - 只是您应该选择您的战斗。优化大多数程序中代码的可读性,并在您拥有更复杂的算法,或者您正在处理低级图形或复杂的数据结构/算法时优化性能,然后,仅当您经过测试时你的程序出了一点问题,发现它运行得很慢。

The compiler will make significant changes to your code, as long as it has the same outcome. Especially in a release (non-debug) build.

This means if you have unused code, declare variables too soon, or have variables that aren't used outside loops, the compiler may get rid of or move them.

/* If you never use these, the compiler will probably throw them out */
int var1;
double var2;
char var3[];
PAINTSTRUCT ps;
HDC hdc;

/* Nothing here effects other code, so the code will probably be removed */
for(int i = 0; i < 100000; ++i)
{
    int j = i * 7;
}

Unless you have really strong performance requirements, the best things you can do is make your code more readable. If a variable is used in a smaller scope, place it there because it is easier to read, not because it might make your program faster.

Computers are really good at running the type of code you are talking about, where you are just using the CPU and memory. Places where you can actually get a good performance improvement are when you are dealing with relatively slow devices, like the network, or reading from the disk. In those cases, single bytes of memory matter.

The place where CPU/memory optimizations make the most sense is in more complex algorithms, or when you are working with a lot of data, like a graphics or search algorithm.

This isn't to say that you shouldn't think about optimization - just that you should pick your battles. Optimize the readability of your code in most of your program, and optimize the performance when you have a more complex algorithm, or you're dealing with low-level graphics or complex data structures/algorithms, and then, only when you've tested your program out a bit, and find out it is running slow.

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