title: OTL library - SQL Server - C++ - Performance
body: <p>I have recently started testing the <strong>OTL library</strong> with the <strong>SQL Server</strong> using the <strong>Visual Studio 2013</strong>. My tests demonstrated that the performance of simple select statements against a 10000 count table is 40% slower than the performance of a <strong>similar .NET 4.0</strong> test application. All tests  were performed with all optimizations turned on for both platforms.</p>
  
  <p>Both apps perform the following tasks:
   Open the db connection
   Create (and reserve space) for the container object.
   Execute the select statement command.
   For each record fetched from db
      create an entity using the db(stream/reader) object
      add the object to container
   close </p>
  
  <p>.NET C# app requires 0.5 secs to complete this task, while OTL-C++ app takes 0.7 secs to complete and I wonder <strong>if it is possible to optimize the C++ app to perform faster</strong>?</p>
  
  <p>Snippet of C++ code:</p>
  
  <pre><code>#define OTL_ODBC_MSSQL_2008     // Compile OTL 4/ODBC, MS SQL 2008
  #define OTL_CPP_11_ON
  #define OTL_STL                 // Turn on STL features
  #define OTL_ANSI_CPP            // Turn on ANSI C++ typecasts
  #define OTL_UNICODE             // Enable Unicode OTL for ODBC
  #include "otlv4.h"    
   class Employee
  
  {
  private:
      int employeeId;
      wstring regno;
      wstring name;
      wstring surname;
  
  public:
      Employee()
      {
      }
  
      Employee(otl_stream&amp; stream)
      {
          unsigned short _regno[32];
          unsigned short _name[32];
          unsigned short _surname[32];
  
          if (!stream.is_null())
          {
              stream &gt;&gt; employeeId;
          }
  
          if (!stream.is_null())
          {
              stream &gt;&gt; (unsigned char*)_regno;
              regno = (wchar_t*)_regno;
          }
  
          if (!stream.is_null()){
              stream &gt;&gt; (unsigned char*)_name;
              name = (wchar_t*)_name;
          }
  
  
          if (!stream.is_null()){
              stream &gt;&gt; (unsigned char*)_surname;
              surname = (wchar_t*)_surname;
          }
      }
  
      int GetEmployeeId() const
      {
          return employeeId;
      }
  };
  
  
  
  otl_connect db;
  int main()
  {
      otl_connect::otl_initialize();
      try
      {
  otl_connect::otl_initialize();
      try
      {
          // connect
          db.rlogon("DSN=SQLODBC");
  
          // start timing
          clock_t begin = clock();
          otl_stream i(10000, "SELECT Id, Field1, Field2, Field3 FROM Test", db);
  
          // create container
          vector&lt;Employee&gt; employeeList;
          employeeList.reserve(10000);
  
          // iterate and fill container
          while (!i.eof())
          {
              Employee employee(i);
              employeeList.push_back(employee);
          }
          i.close();
  
          // cleanup
          size_t size = employeeList.size();  
          clock_t end = clock();
          double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
          cout &lt;&lt; "Total records:" &lt;&lt; size &lt;&lt; endl;
          cout &lt;&lt; "Time elapsed to read all records:" &lt;&lt; elapsed_secs &lt;&lt; endl;
  
  
  
      }
  
      catch (otl_exception&amp; p){ // intercept OTL exceptions
          cerr &lt;&lt; p.msg &lt;&lt; endl; // print out error message
          cerr &lt;&lt; p.stm_text &lt;&lt; endl; // print out SQL that caused the error
          cerr &lt;&lt; p.sqlstate &lt;&lt; endl; // print out SQLSTATE message
          cerr &lt;&lt; p.var_info &lt;&lt; endl; // print out the variable that caused the error
      }
  
      db.logoff();
  return EXIT_SUCCESS;
  }
  </code></pre>