Live data from Hacker News

Why Const Doesn't Make C Code Faster

theartofmachinery.com

191–197 of 197 posts

Re: Why Const Doesn't Make C Code Faster

#191

I hardly ever bother optimizing my code anymore, with -O3 nothing I do ever really seems to make a difference. The real reason to use "const" is to show intent. See "Const and Rigid Parameters" in this wonderful article about the Doom 3 source code: https://kotaku.com/the-exceptional-beauty-of-doom-3s-source-...

I find that I can sometimes get significant speedups by changing data access patterns when considering cache. I have found this to be the first and most valuable thing to tune, before attempting SIMD.

Interesting! Any rules-of-thumb you can share about that process?

Re: Why Const Doesn't Make C Code Faster

#192
post #118

Earlier quoted context omitted.

> won't guarantee that some other thread of execution won't change the value under your nose My understanding is that compilers can always assume that there is no other thread involved, which (part of) why C11 atomics are necessary. Is that not the case?

Yes, but it can't assume any random function call it does doesn't use a different pointer to the same object which is not const. So, even if you don't cast const to non-const pointers you can run into the const value changing.

Concrete example:

  void foo(const int* const p1, int* const p2) {
    int a = *p1;
    *p2 += 42;
    int b = *p1;
    return a == b; // b = a + 42
  }
  int main() {
    int x = 0;
    return foo(&x, &x);
  }

Re: Why Const Doesn't Make C Code Faster

#193

Earlier quoted context omitted.

Does it enforce these attributes or are they just a promise by the code author?

D has a `pure` attribute for functions, and yes it is enforced. It's enforced even to the point where it becomes a PITA, but when you manage to make functions pure, you know it's solid. One pain point with pure functions is you can't insert debug logging statements. D has a special case for that - purity for a statement isn't checked if it is prefixed with the `debug` keyword: pure int square(int x) { debug printf("c…

Furthermore AFAIK things prefixed with debug don't get compiled into release binaries either.

Re: Why Const Doesn't Make C Code Faster

#194
post #18

Unfortunately in C++, the compiler is not allowed to assume that if it passes a const reference to a function, that function will not change the object. The function is allowed to cast away const and modify the object. I'm not happy that they did it that way; I would have preferred it if cast-away-const were more restricted (for example, allowed when calling a child function that takes a char* but doesn't modify the…

I find it awesome that you can do that, the extra flexibility is great, e.g. when you're working with const char* arrays, sometimes, you need to create a copy of that char array, but save its pointer (char* ) in a (const char* ) variable, but you're still going to need to delete that copy later... and then you're glad that you can simply recast a (const char* ) into (char* ). I save the data of whether or not it's a…

Couldn't you use a union for that?

  class string {
    
    union {
       const char *referenced;
       char *copied;
    } data;
    bool copied;
    
  public:
    
    string(const char *source, booly copy) {
      if(copy) {
        data.copied = strdup(source);
        copied = true;
      } else {
        data.referenced = source;
        copied = false;
      }
    }
    
    operator const char *() const {
      return copied ? data.copied : data.referenced;
    }
    
    ~string() {
      if(copied) {
        free(data.copied);
      }
    }
    
  };
No const_cast and no wasted memory and it's clear that you are storing two semantically different types.

I would expect the conversion operator to optimize down to a noop since in all cases the returned address is equal to this.

Re: Why Const Doesn't Make C Code Faster

#195

I used to strive for "const correctness" in my game engine code, and wasted a fair amount of time fighting the compiler and editing function signatures as requirements changed. Mostly eliminating const from the codebase simplified things a lot. Didn't do any comparison studies of performance, but the productivity boost from not having to think about it was nice, and I suspect any performance difference is margin-of-e…

Productivity boost from not writing tests or thinking about function preconditions is also nice ... until it isn't.

Re: Why Const Doesn't Make C Code Faster

#196

Earlier quoted context omitted.

I find it awesome that you can do that, the extra flexibility is great, e.g. when you're working with const char* arrays, sometimes, you need to create a copy of that char array, but save its pointer (char* ) in a (const char* ) variable, but you're still going to need to delete that copy later... and then you're glad that you can simply recast a (const char* ) into (char* ). I save the data of whether or not it's a…

Couldn't you use a union for that? class string { union { const char *referenced; char *copied; } data; bool copied; public: string(const char *source, booly copy) { if(copy) { data.copied = strdup(source); copied = true; } else { data.referenced = source; copied = false; } } operator const char *() const { return copied ? data.copied : data.referenced; } ~string() { if(copied) { free(data.copied); } } }; No const_ca…

Yes, that could work too, but in my opinion, only unnecessarily complicates things.

I want the pointer (actually, that to what it's pointing to) to be referenced as const in all cases, except when I create a copy or delete that copy, in which case I then explicitly recast them as not-const. That's just two tiny exceptions in code I have to write anyways.

Such as it is, I would only consider a union of them if I'd actually need const/non-const 50/50 of the time, but my current use case is more like 98/2.

Apart from that, I'm guessing you're from a C++ background, as there are no classes in C? (and also, if you use C++, it's recommended to use "delete" instead of "free", since the latter is a C function)

EDIT: Actually, it's only one exception/re-cast, when I delete it, as no compiler would complain about saving a char* in a const char* data type.

Re: Why Const Doesn't Make C Code Faster

#197

Earlier quoted context omitted.

AFAIK placement new does launder. But both new and launder have no effect on their argument (well, placement new of course constructs an object there), they only 'bless' pointer returned from it. The use case is if you placement new on some byte storage. Now you want to access the object stored there, and of course you do not want to placement new the storage again, nor you have cached the result of the previous plac…

> AFAIK placement new does launder. But both new and launder have no effect on their argument (well, placement new of course constructs an object there), they only 'bless' pointer returned from it. I may be misunderstanding, but this seems to directly contradict what the linked paper says: > Note that std::launder() does not “white wash” the pointer for any further usage. > The obvious question is, why don’t we simpl…

> I may be misunderstanding, but this seems to directly contradict what the linked paper says: >> Note that std::launder() does not “white wash” the pointer for any further usage.

no, it is consistent. Launder does not white wash its parameter, only its return pointer and any pointer returned by it. Same for placement new.

Post reply on HN