diff --git a/ov-base.h b/ov-base4.h
index 50593f1..d5c6fe3 100644
--- a/ov-base.h
+++ b/ov-base4.h
@@ -160,26 +160,30 @@ DEF_CLASS_TO_BTYP (char, btyp_char);
 #define DECLARE_OV_BASE_TYPEID_FUNCTIONS_AND_DATA       \
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA2(virtual)
 
-#define DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA2(VIRTUAL)                  \
-  public:                                                               \
-    VIRTUAL int type_id (void) const { return t_id; }                   \
-    VIRTUAL std::string type_name (void) const { return t_name; }       \
-    VIRTUAL std::string class_name (void) const { return c_name; }      \
-    static int static_type_id (void) { return t_id; }                   \
-    static std::string static_type_name (void) { return t_name; }       \
-    static std::string static_class_name (void) { return c_name; }      \
-    static void register_type (void);                                   \
-    static void register_type (octave::type_info&);                     \
-                                                                        \
-  private:                                                              \
-    static int t_id;                                                    \
-    static const std::string t_name;                                    \
-    static const std::string c_name;
+#define DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA2(VIRTUAL)                          \
+  public:                                                                       \
+    VIRTUAL int type_id (void) const { return t_id; }                           \
+    VIRTUAL std::string type_name (void) const { return t_name; }               \
+    VIRTUAL std::string class_name (void) const { return c_name; }              \
+    static int static_type_id (void) { return t_id; }                           \
+    static std::string static_type_name (void) { return t_name; }               \
+    static std::string static_class_name (void) { return c_name; }              \
+    static void* operator new (size_t sz) { return pool.alloc (sz); }           \
+    static void operator delete (void *ptr, size_t sz) { pool.free (ptr, sz); } \
+    static void register_type (void);                                           \
+    static void register_type (octave::type_info&);                             \
+                                                                                \
+  private:                                                                      \
+    static int t_id;                                                            \
+    static const std::string t_name;                                            \
+    static const std::string c_name;                                            \
+    thread_local static memory_pool pool;
 
 #define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)            \
   int t::t_id (-1);                                             \
   const std::string t::t_name (n);                              \
   const std::string t::c_name (c);                              \
+  thread_local memory_pool t::pool (sizeof (t));                \
   void t::register_type (void)                                  \
   {                                                             \
     octave::type_info& type_info                                \
@@ -193,6 +197,68 @@ DEF_CLASS_TO_BTYP (char, btyp_char);
     t_id = ti.register_type (t::t_name, t::c_name, v);          \
   }
 
+// A simple memory pool to increase performance of 
+// the allocation of small objects.
+
+class memory_pool
+{
+public:
+
+  memory_pool (size_t elem_size, size_t pool_size = 1000)
+  : item_size(elem_size), max_size (pool_size), free_list ()
+  {  }
+
+  ~memory_pool ()
+  {
+    for (void *item : free_list)
+        ::operator delete (item);
+  }
+
+  void *alloc (size_t sz)
+  {
+    if (sz != item_size)
+      return ::operator new (sz);
+
+    if (free_list.empty ())
+      return ::operator new (item_size);
+
+    void *retval = free_list.back ();
+
+    free_list.pop_back ();
+
+    return retval;
+  }
+
+  void free (void *ptr, size_t sz) noexcept
+  {
+    if (! ptr)
+      return;
+
+    if (sz != item_size || free_list.size () == max_size)
+      return ::operator delete (ptr);
+
+    // A deallocation function shouldn't throw.
+    // push_back may throw in rare cases.  
+
+    try
+      {
+        free_list.push_back (ptr);
+      }
+    catch (...)
+      {
+        ::operator delete (ptr);
+      }
+  }
+
+private:
+
+  const size_t item_size ;
+
+  const size_t max_size ;
+
+  std::vector<void *> free_list;
+};
+
 // A base value type, so that derived types only have to redefine what
 // they need (if they are derived from octave_base_value instead of
 // octave_value).
