Consider this piece of code
| 34 static bool
| 35 _valid_character(char *str, size_t *idx)
| 36 {
| 37 char c = str[*idx];
| 38
| 39 if (c != '\\' && c != '"') {
| 40 (*idx) += 1;
| 41 return true;
| 42 } else if (c == '"') {
| 43 return false;
| 44 } else {
| 45 char b = str[(*idx) + 1];
| 46 switch (b) {
| 47 case '"':
| 48 case '\\':
| 49 case '/':
| 50 case 'b':
| 51 case 'f':
| 52 case 'n':
| 53 case 'r':
| 54 case 't':
| 55 (*idx) += 2;
| 56 return true;
| 57 default:
| 58 pprint_error("%s@%s:%d invalid escape sequnce \\%c%c (aborting)",
| 59 __FILE_NAME__, __func__, __LINE__, c, b);
| 60 abort();
| 61 }
| 62 }
| 63 }
This one function is the root cause of a meaning full slowdown in my code. I have tried only using if statements and only using switch statements but this is the best optimization that I can come up with where callgrind results in the best performance. This function accounts for about 25% of the runtime so by the questionable (sorry) 80/20 rule its in my best interest to make this code faster.
Below is the callgrind output visualized with kcachegrind on this function.
It seems callgrind is saying that my first jump is the worst jump but I have tried all combinations of this if statement to try to minimize jumping and every time the first jump is the worst jump.
This code was compiled with clang
clang ... -Weverything -Werror -Wpedantic -m64 -O0 -g
So my question is what is the best way to go about optimizing this code and alternative techniques including assembly modification to optimize this simple yet deadly piece of code.
I would like to keep using -O0
since I find it the most useful for debugging and finding optimizations. -O1,2,3,fast
tend to abstract to much away to get a good understanding of what is happening.
-- Edit 1 It was asked for an example input.
char cstr[BUF] = "abcdefghijklmnopqrstuvwxyz\"randomgarbageafterthis";
size_t idx = 0;
while (_valid_character(cstr, &idx));
In the end the input is just a string and a loop is called until the end "
character. The ending idx value holds cstr[idx] == '"''
to be true.