title: Implementing a Type-erased list for fast write/read
body: <p>I am trying to implement a type erased data structure for writing and
  reading large arrays of any type in a list, with the following
  requirements:</p>
  
  <ul>
  <li>Fast insert of bulk data (receive a <code>std::vector&lt;T&gt;</code>, where T is a primitive type).</li>
  <li>Fast read of all/latest values if types match</li>
  <li>Read/convert if types mismatch. In most cases from primitive to primitive (e.g double->float, int->double)</li>
  </ul>
  
  <p>The interface I was thinking of would look something like this:</p>
  
  <pre><code>class Trace {
        template&lt;typename T&gt; std::vector&lt;T&gt; read();
        template&lt;typename T&gt; std::vector&lt;T&gt; latest();
        template&lt;typename T&gt; void append(std::vector&lt;T&gt; values);
        template&lt;typename T&gt; void replace(std::vector&lt;T&gt; values);
        void clear();
  };
  </code></pre>
  
  <p>Which is then used in a TraceHandler class (Singleton structure), which allows access to traces per key:</p>
  
  <pre><code>class TraceHandler {
  public:
    template&lt;typename T&gt;
    std::vector&lt;T&gt; read(std::string const&amp; key);
    template&lt;typename T&gt;
    void write(std::string const&amp; key, std::vector&lt;T&gt; const&amp; val);
  private:
    // STore all Traces for different types
  };
  </code></pre>
  
  <p>And a useage would look something like this:</p>
  
  <pre><code>TraceHandler th;
  std::vector&lt;double&gt; vals(1000,1.0), res;
  th.write("values",vals);
  std::vector&lt;int&gt; resInt;
  res = th.read&lt;double&gt;("values");
  resInt = th.read&lt;int&gt;("values");
  </code></pre>
  
  <p>Our current implementation creates a Trace for each datatype and the
  user has to keep track of the correct type, which is not very
  flexible (e.g write using <code>writeDouble()</code>, read using <code>readDouble</code>).</p>
  
  <p>My first approach was to change the type of the internal storage
  vector to an <code>any</code> type (we are using Poco libraries, so I was using
  <code>Poco::Any</code> and <code>Poco::DynamicAny</code>), but this leads to a big
  performance hit.</p>
  
  <p>Data is written from Devices with high frequencies (data is acquired
  with up to 20khz, then written in blocks of around 4k to the Trace),
  and the measured performance difference between a plain vector and one
  of an Any type was of factor 500-1000 (measured 800ms vs. 4ms for big
  bulk insert/read in a loop). Most of the time gets lost due to
  constructor calls vs simple memcopy.</p>
  
  <p>So my question is: Is there a way to implement this interface (or an
  alternative) with good bulk insert/read performance?</p>
  
  <hr>
  
  <p>Edit:
  This is the current implementation I'm using:</p>
  
  <pre><code>class LWDynamicVector
  {
  private:
    typedef std::vector&lt;Poco::DynamicAny&gt; DataList;   
    DataList m_data;
  public:
    LWDynamicVector() {}
  
    template&lt;typename T&gt; std::vector&lt;T&gt; read() {
      return std::vector&lt;T&gt;(m_data.begin(),m_data.end());
    }
  
    template&lt;typename T&gt; void writeAppend(std::vector&lt;T&gt; v) {
      m_data.insert(m_data.end(),v.begin(),v.end());
      }
  
    template&lt;typename T&gt; void writeReplace(std::vector&lt;T&gt; v) {
      m_data.assign(v.begin(),v.end());
    }
  };
  </code></pre>
  
  <p>And the Test I am using:</p>
  
  <pre><code>TEST(DynamicVector,Performance) {
    typedef double Type;
    size_t runs = 100; size_t N = 20480;
    std::vector&lt;Type&gt; input;
    input.reserve(N);
    for(size_t i = 0; i &lt; N; ++i) {
      input.push_back(rand());
    }
  
    {
      OldVector&lt;Type&gt; instance;
      Poco::Timestamp ts;
      for(size_t i = 0; i &lt; runs; ++i) {
        instance.writeAppend(input);
      }
      std::cout &lt;&lt; "Old vector: time elapsed(ms) = " &lt;&lt; ts.elapsed() / 1000.0 &lt;&lt; std::endl; 
      std::vector&lt;Type&gt; output = instance.read();
      EXPECT_EQ(output.back(),output.back()); 
    }
    {
      LWDynamicVector dbv;
      Poco::Timestamp ts;
      for(size_t i = 0; i &lt; runs; ++i) {
        dbv.writeAppend(input);
      }
      std::cout &lt;&lt; "New vector: time elapsed(ms) = " &lt;&lt; ts.elapsed() / 1000.0 &lt;&lt; std::endl;
  
      std::vector&lt;Type&gt; output = dbv.read&lt;Type&gt;();
      EXPECT_EQ(output.back(),output.back());
    }
  
  }
  </code></pre>
  
  <p>Which results in:</p>
  
  <pre><code>Old vector: time elapsed(ms) = 44.004
  New vector: time elapsed(ms) = 4380.44
  </code></pre>
  
  <p>Regarding compiler options and optimizations: Unfortunately I'm stuck at the current settings without the option to change them. In most scenarios the build runs in debug mode, but still has to meet the timing requirements. But anyways, the performance does not improve in release mode:</p>
  
  <pre><code>Old vector: time elapsed(ms) = 20.002
  New vector: time elapsed(ms) = 1013.1
  </code></pre>