瀏覽代碼

inlined `tuple`

blueloveTH 2 年之前
父節點
當前提交
27aa41fc35
共有 2 個文件被更改,包括 27 次插入22 次删除
  1. 1 0
      src/cffi.h
  2. 26 22
      src/tuplelist.h

+ 1 - 0
src/cffi.h

@@ -339,6 +339,7 @@ struct C99ReflType final: ReflType{
 };
 
 static_assert(sizeof(Py_<C99Struct>) <= 64);
+static_assert(sizeof(Py_<Tuple>) <= 64);
 
 inline PyObject* py_var(VM* vm, void* p){
     return VAR_T(VoidP, p);

+ 26 - 22
src/tuplelist.h

@@ -11,10 +11,17 @@ using List = pod_vector<PyObject*>;
 
 class Tuple {
     PyObject** _args;
+    PyObject* _inlined[3];
     int _size;
 
+    bool is_inlined() const { return _args == _inlined; }
+
     void _alloc(int n){
-        this->_args = (n==0) ? nullptr : (PyObject**)pool64.alloc(n * sizeof(void*));
+        if(n <= 3){
+            this->_args = _inlined;
+        }else{
+            this->_args = (PyObject**)pool64.alloc(n * sizeof(void*));
+        }
         this->_size = n;
     }
 
@@ -27,40 +34,38 @@ public:
     }
 
     Tuple(Tuple&& other) noexcept {
-        this->_args = other._args;
-        this->_size = other._size;
-        other._args = nullptr;
-        other._size = 0;
+        _size = other._size;
+        if(other.is_inlined()){
+            _args = _inlined;
+            for(int i=0; i<_size; i++) _args[i] = other._args[i];
+        }else{
+            _args = other._args;
+            other._args = other._inlined;
+            other._size = 0;
+        }
     }
 
-    Tuple(std::initializer_list<PyObject*> list) : Tuple(list.size()){
-        int i = 0;
-        for(PyObject* p : list) _args[i++] = p;
-    }
-
-    Tuple(List&& other) noexcept : Tuple(other.size()){
+    Tuple(List&& other) noexcept {
+        _size = other.size();
         _args = other._data;
         other._data = nullptr;
     }
 
+    Tuple(std::initializer_list<PyObject*> list) {
+        _alloc(list.size());
+        int i = 0;
+        for(PyObject* obj: list) _args[i++] = obj;
+    }
+
     PyObject*& operator[](int i){ return _args[i]; }
     PyObject* operator[](int i) const { return _args[i]; }
 
-    Tuple& operator=(Tuple&& other) noexcept {
-        if(_args!=nullptr) pool64.dealloc(_args);
-        this->_args = other._args;
-        this->_size = other._size;
-        other._args = nullptr;
-        other._size = 0;
-        return *this;
-    }
-
     int size() const { return _size; }
 
     PyObject** begin() const { return _args; }
     PyObject** end() const { return _args + _size; }
 
-    ~Tuple(){ if(_args!=nullptr) pool64.dealloc(_args); }
+    ~Tuple(){ if(!is_inlined()) pool64.dealloc(_args); }
 };
 
 // a lightweight view for function args, it does not own the memory
@@ -70,7 +75,6 @@ struct ArgsView{
 
     ArgsView(PyObject** begin, PyObject** end) : _begin(begin), _end(end) {}
     ArgsView(const Tuple& t) : _begin(t.begin()), _end(t.end()) {}
-    ArgsView(): _begin(nullptr), _end(nullptr) {}
 
     PyObject** begin() const { return _begin; }
     PyObject** end() const { return _end; }