about summary refs log tree commit diff
path: root/src/libexpr/value.hh
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2015-07-23T20·05+0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2015-07-23T20·05+0200
commitb83801f8b3b48f4d69414401c8a51724946a8666 (patch)
tree912be85806c1d0ebc49dfafc0431eca0ee928655 /src/libexpr/value.hh
parent14be783676adbb3517b2f73fee31c6f341575440 (diff)
Optimize small lists
The value pointers of lists with 1 or 2 elements are now stored in the
list value itself. In particular, this makes the "concatMap (x: if
cond then [(f x)] else [])" idiom cheaper.
Diffstat (limited to 'src/libexpr/value.hh')
-rw-r--r--src/libexpr/value.hh29
1 files changed, 26 insertions, 3 deletions
diff --git a/src/libexpr/value.hh b/src/libexpr/value.hh
index c06b5a6d11..e6d1502cb6 100644
--- a/src/libexpr/value.hh
+++ b/src/libexpr/value.hh
@@ -12,7 +12,9 @@ typedef enum {
     tPath,
     tNull,
     tAttrs,
-    tList,
+    tList1,
+    tList2,
+    tListN,
     tThunk,
     tApp,
     tLambda,
@@ -119,9 +121,10 @@ struct Value
         const char * path;
         Bindings * attrs;
         struct {
-            unsigned int length;
+            unsigned int size;
             Value * * elems;
-        } list;
+        } bigList;
+        Value * smallList[2];
         struct {
             Env * env;
             Expr * expr;
@@ -139,6 +142,26 @@ struct Value
         } primOpApp;
         ExternalValueBase * external;
     };
+
+    bool isList() const
+    {
+        return type == tList1 || type == tList2 || type == tListN;
+    }
+
+    Value * * listElems()
+    {
+        return type == tList1 || type == tList2 ? smallList : bigList.elems;
+    }
+
+    const Value * const * listElems() const
+    {
+        return type == tList1 || type == tList2 ? smallList : bigList.elems;
+    }
+
+    unsigned int listSize() const
+    {
+        return type == tList1 ? 1 : type == tList2 ? 2 : bigList.size;
+    }
 };