diff options
author | Yorhel <git@yorhel.nl> | 2013-01-13 14:29:38 +0100 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2013-01-13 14:29:38 +0100 |
commit | 06b08a6945caeb8a888457cf2cf16a3febf377cc (patch) | |
tree | ffb236701ed34ee96aab44ba637adb5c09dbe539 | |
parent | 51103dd526684c145753f828845280ab4e548bad (diff) |
ecbuf: Use gcc hints to indicate that buffer resizes aren't common
This provided a ~1.2 to 2 times performance improvement in the
benchmark.
-rw-r--r-- | ecbuf.h | 14 |
1 files changed, 10 insertions, 4 deletions
@@ -98,6 +98,12 @@ typedef struct { #define ecbuf_peek(e) ((e).a[(e).v.o]) +#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) +#define ecbuf__unlikely(expr) (__builtin_expect(expr, 0)) +#else +#define ecbuf__unlikely(expr) (expr) +#endif + static inline void *ecbuf__push(ecbuf_vars_t *v, void **a, size_t alen) { /* The algortihm is something like: * 1. If the buffer is full, "grow" it @@ -108,7 +114,7 @@ static inline void *ecbuf__push(ecbuf_vars_t *v, void **a, size_t alen) { */ int i, obn = v->bn; /* 1 */ - if(v->l == v->bn) { + if(ecbuf__unlikely(v->l == v->bn)) { v->bn <<= 1; if(v->cn == obn) { if(v->o) v->b = (v->o - 1 + v->cn) & (v->cn-1); @@ -120,8 +126,8 @@ static inline void *ecbuf__push(ecbuf_vars_t *v, void **a, size_t alen) { if(v->bn == v->cn) i &= v->cn-1; else if(v->o <= v->b) i += v->cn; /* 3 */ - if(i >= v->bn) v->bn <<= 1; - if(v->bn != obn) *a = realloc(*a, v->bn*alen); + if(ecbuf__unlikely(i >= v->bn)) v->bn <<= 1; + if(ecbuf__unlikely(v->bn != obn)) *a = realloc(*a, v->bn*alen); v->l++; return ((char *)*a)+alen*i; } @@ -133,7 +139,7 @@ static inline void *ecbuf__push(ecbuf_vars_t *v, void **a, size_t alen) { static inline int ecbuf__pop(ecbuf_vars_t *v) { int l = v->o; v->l--; - if(v->o == v->b) { + if(ecbuf__unlikely(v->o == v->b)) { v->o = v->cn; v->cn = v->bn; v->b = -1; |