summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2013-01-13 14:29:38 +0100
committerYorhel <git@yorhel.nl>2013-01-13 14:29:38 +0100
commit06b08a6945caeb8a888457cf2cf16a3febf377cc (patch)
treeffb236701ed34ee96aab44ba637adb5c09dbe539
parent51103dd526684c145753f828845280ab4e548bad (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.h14
1 files changed, 10 insertions, 4 deletions
diff --git a/ecbuf.h b/ecbuf.h
index deb4521..c279c0e 100644
--- a/ecbuf.h
+++ b/ecbuf.h
@@ -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;