While programming optimization that makes ones' code completely unreadable is often a bad thing, there are places for it, like that one inner loop of your code that takes up 98% of the program's running time.
What are you tricks for improving performance in C, other than the obvious inline assembly or the like?
>>157
Stuffing your FOR loop full of this shit isn't going to make your code run any faster.
Name:
Anonymous2008-02-07 16:36
#include <stdlib.h>
#include <stdio.h>
char* main() {
char* DATA = malloc(4097);
printf("REAL `DATA' SIZE: %u\n", *(unsigned int*)(DATA - 4));
return DATA; /* ONLY PUSSEYS FREE THERE MEMORT; LET THE DOS DO IT!!! */
}
>>164 >>163
Actually, it originates from a program called QED, originally written in the late 1960s by Butler Lampson and Peter Deutsch. Their version had the command SUBSTITUTE /x/ FOR /y/. Ken Thompson (of Unix fame) then wrote a version for MIT's CTSS system, and shortened the substitution command to just s/x/y/ - and, crucially, added regular expression support to it. Thompson later wrote Unix's standard editor ed, taking a lot of features from QED, including s//. It was the massive spread of Unix that so popularised this idiom.
Name:
Anonymous2008-02-07 16:56
from sys/cdefs.h: /*
* Compiler-dependent macros to help declare dead (non-returning) and
* pure (no side effects) functions, and unused variables. They are
* null except for versions of gcc that are known to support the features
* properly (old versions of gcc-2 supported the dead and pure features
* in a different (wrong) way). If we do not provide an implementation
* for a given compiler, let the compile fail if it is told to use
* a feature that we cannot live without.
*/
#ifdef lint
#define __dead2
#define __pure2
#define __unused
#define __packed
#define __aligned(x)
#define __section(x)
#else
#if !__GNUC_PREREQ__(2, 5) && !defined(__INTEL_COMPILER)
#define __dead2
#define __pure2
#define __unused
#endif
#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7 && !defined(__INTEL_COMPILER)
#define __dead2 __attribute__((__noreturn__))
#define __pure2 __attribute__((__const__))
#define __unused
/* XXX Find out what to do for __packed, __aligned and __section */
#endif
#if __GNUC_PREREQ__(2, 7)
#define __dead2 __attribute__((__noreturn__))
#define __pure2 __attribute__((__const__))
#define __unused __attribute__((__unused__))
#define __used __attribute__((__used__))
#define __packed __attribute__((__packed__))
#define __aligned(x) __attribute__((__aligned__(x)))
#define __section(x) __attribute__((__section__(x)))
#endif
#if defined(__INTEL_COMPILER)
#define __dead2 __attribute__((__noreturn__))
#define __pure2 __attribute__((__const__))
#define __unused __attribute__((__unused__))
#define __used __attribute__((__used__))
#define __packed __attribute__((__packed__))
#define __aligned(x) __attribute__((__aligned__(x)))
#define __section(x) __attribute__((__section__(x)))
#endif
#endif
/*
* GCC 2.95 provides `__restrict' as an extension to C90 to support the
* C99-specific `restrict' type qualifier. We happen to use `__restrict' as
* a way to define the `restrict' type qualifier without disturbing older
* software that is unaware of C99 keywords.
*/
#if !(__GNUC__ == 2 && __GNUC_MINOR__ == 95)
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901
#define __restrict
#else
#define __restrict restrict
#endif
#endif
/*
* GNU C version 2.96 adds explicit branch prediction so that
* the CPU back-end can hint the processor and also so that
* code blocks can be reordered such that the predicted path
* sees a more linear flow, thus improving cache behavior, etc.
*
* The following two macros provide us with a way to utilize this
* compiler feature. Use __predict_true() if you expect the expression
* to evaluate to true, and __predict_false() if you expect the
* expression to evaluate to false.
*
* A few notes about usage:
*
* * Generally, __predict_false() error condition checks (unless
* you have some _strong_ reason to do otherwise, in which case
* document it), and/or __predict_true() `no-error' condition
* checks, assuming you want to optimize for the no-error case.
*
* * Other than that, if you don't know the likelihood of a test
* succeeding from empirical or other `hard' evidence, don't
* make predictions.
*
* * These are meant to be used in places that are run `a lot'.
* It is wasteful to make predictions in code that is run
* seldomly (e.g. at subsystem initialization time) as the
* basic block reordering that this affects can often generate
* larger code.
*/
#if __GNUC_PREREQ__(2, 96)
#define __predict_true(exp) __builtin_expect((exp), 1)
#define __predict_false(exp) __builtin_expect((exp), 0)
#else
#define __predict_true(exp) (exp)
#define __predict_false(exp) (exp)
#endif
>>167
Fuck off Guido, stop posting CPython source code
Name:
Anonymous2008-02-07 20:17
These are meant to be used in places that are run `a lot' that are run `a lot' run `a lot' `a lot'
Name:
Anonymous2008-03-18 8:15
Here's a little secret that allows you to save memory when allocating structures: struct s { int a; char b };
struct s s1 = malloc(sizeof(struct s)); /* OH NO MASSIVE MEMORY WASTE */
struct s s2 = malloc(offsetof(struct s, b) + sizeof(char)); /* YAY MEMORY SAVED */
If you don't have offsetof (stddef.h), it can be implemented liek this:
>>170
What, you save about 3 bytes in memory? Big deal. Unless you're programming an embedded system in which every byte is precious, you'd better stick with the more widely-used and more readable "malloc(sizeof(struct s))".
>>181
Please read the rest of this thread before continuing. This thread is about secret tricks of the C language that work well (most of the time), but may not have totally defined behavior or be very portable.