﻿# About optimizations

Verifying the recommendation "Don't do the compilers job" from the book "The Ultimate Question of Programming, Refactoring, and Everything"\. 

_Note\. The article was first [published](https://32bit-me.livejournal.com/124489.html) in_ _Russian_ _on_ _livejournal\.com\._ _The_ _article_ _and_ _is_ _translation_ _are_ _posted_ _on_ _our_ _website_ _with_ _the_ _author's_ _permission\._ 

In the blog of PVS\-Studio team you can find many examples of errors made by programmers and the recommendations of how you can avoid these mistakes \([link](https://pvs-studio.com/en/blog/posts/cpp/0391/)\)\.

The first piece of advice: don't do the compilers job\. Do not optimize manually those fragments that will be optimized anyway\. As an example we see a code fragment taken from MySQL project where a programmer deployed a loop manually and made a mistake\. Further on, the author says if we write this function with a loop, the compiler will most likely deploy it itself\. 

Let's check it with the help of the [online compiler](https://gcc.godbolt.org/)\. I copied the source code of function from the article and edited them a little bit so that they would compile without any additional files\. 

The compilation was done with the help of clang 3\.9 compiler for the arm target with the optimization level \-O2 \(with these settings the compiler deploys the loops\)\.

So, here is the original source code:

```cpp
int rr_cmp(unsigned char *a, unsigned char *b)
{
  if (a[0] != b[0])
    return (int) a[0] - (int) b[0];
  if (a[1] != b[1])
    return (int) a[1] - (int) b[1];
  if (a[2] != b[2])
    return (int) a[2] - (int) b[2];
  if (a[3] != b[3])
    return (int) a[3] - (int) b[3];
  if (a[4] != b[4])
    return (int) a[4] - (int) b[4];
  if (a[5] != b[5])
    return (int) a[5] - (int) b[5];
  if (a[6] != b[6])
    return (int) a[6] - (int) b[6];
  return (int) a[7] - (int) b[7];
}
```

The result for arm:

```cpp
rr_cmp(unsigned char*, unsigned char*):
@ @rr_cmp(unsigned char*, unsigned char*)
        ldrb    r2, [r1]
        ldrb    r3, [r0]
        cmp     r3, r2
        bne     .LBB0_7
        ldrb    r2, [r1, #1]
        ldrb    r3, [r0, #1]
        cmp     r3, r2
        bne     .LBB0_7
        ldrb    r2, [r1, #2]
        ldrb    r3, [r0, #2]
        cmp     r3, r2
        bne     .LBB0_7
        ldrb    r2, [r1, #3]
        ldrb    r3, [r0, #3]
        cmp     r3, r2
        bne     .LBB0_7
        ldrb    r2, [r1, #4]
        ldrb    r3, [r0, #4]
        cmp     r3, r2
        bne     .LBB0_7
        ldrb    r2, [r1, #5]
        ldrb    r3, [r0, #5]
        cmp     r3, r2
        bne     .LBB0_7
        ldrb    r2, [r1, #6]
        ldrb    r3, [r0, #6]
        cmp     r3, r2
        ldrbeq  r1, [r1, #7]
        ldrbeq  r0, [r0, #7]
        subeq   r0, r0, r1
        bxeq    lr
.LBB0_7:
        sub     r0, r3, r2
        bx      lr
```



The source code, suggested by the author from PVS\-Studio:

```cpp
int rr_cmp(unsigned char *a,unsigned char *b)
{
  for (int i = 0; i < 7; ++i)
  {
    if (a[i] != b[i])
      return a[i] - b[i]; 
  }
  return a[7] - b[7];
}
```

Result:

```cpp
rr_cmp(unsigned char*, unsigned char*):
@ @rr_cmp(unsigned char*, unsigned char*)
        ldrb    r2, [r1]
        ldrb    r3, [r0]
        cmp     r3, r2
        bne     .LBB0_7
        ldrb    r2, [r1, #1]
        ldrb    r3, [r0, #1]
        cmp     r3, r2
        bne     .LBB0_7
        ldrb    r2, [r1, #2]
        ldrb    r3, [r0, #2]
        cmp     r3, r2
        bne     .LBB0_7
        ldrb    r2, [r1, #3]
        ldrb    r3, [r0, #3]
        cmp     r3, r2
        bne     .LBB0_7
        ldrb    r2, [r1, #4]
        ldrb    r3, [r0, #4]
        cmp     r3, r2
        bne     .LBB0_7
        ldrb    r2, [r1, #5]
        ldrb    r3, [r0, #5]
        cmp     r3, r2
        bne     .LBB0_7
        ldrb    r2, [r1, #6]
        ldrb    r3, [r0, #6]
        cmp     r3, r2
        ldrbeq  r1, [r1, #7]
        ldrbeq  r0, [r0, #7]
        subeq   r0, r0, r1
        bxeq    lr
.LBB0_7:
        sub     r0, r3, r2
        bx      lr
```

Well\.\.\. "Find 10 differences"\.

It's all the same\.

However, oddly enough, the result for x86\-64 will be slightly different\. But this is another story\.