<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" ><channel><title>Blog::Quibb &#187; benchmarks</title> <atom:link href="http://blog.quibb.org/tag/benchmarks/feed/" rel="self" type="application/rss+xml" /><link>http://blog.quibb.org</link> <description>Software development and more.</description> <lastBuildDate>Mon, 21 Nov 2011 05:12:26 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>unitbench 0.1 released!</title><link>http://blog.quibb.org/2011/03/unitbench-0-1-released/</link> <comments>http://blog.quibb.org/2011/03/unitbench-0-1-released/#comments</comments> <pubDate>Tue, 08 Mar 2011 13:23:34 +0000</pubDate> <dc:creator>Joe</dc:creator> <category><![CDATA[Announcement]]></category> <category><![CDATA[Python]]></category> <category><![CDATA[benchmarks]]></category> <category><![CDATA[unitbench]]></category><guid isPermaLink="false">http://blog.quibb.org/?p=331</guid> <description><![CDATA[After writing cppbench, a C++ benchmark framework, I felt inspired to take the next step.  I wanted a benchmark library that was similar to unittest in python.  I started working on unitbench.  I ended up with a library that allows you to start a benchmark with &#8216;bench&#8217; and it will be run and timed.  It [...]]]></description> <content:encoded><![CDATA[<p>After writing <a title="cppbench" href="http://blog.quibb.org/cppbench/">cppbench</a>, a C++ benchmark framework, I felt inspired to take the next step.  I wanted a benchmark library that was similar to <a title="unittest" href="http://docs.python.org/library/unittest.html">unittest</a> in python.  I started working on <a title="unitbench" href="http://blog.quibb.org/unitbench">unitbench</a>.  I ended up with a library that allows you to start a benchmark with &#8216;bench&#8217; and it will be run and timed.  It has functions that can be overloaded to denote the number of warmup runs to perform and the input to the benchmarks.  See the documentation below for full examples and all functions.</p><p><strong>Features:</strong></p><ul><li>BSD License</li><li>Supports python 2.6 &#8211; 3.2</li><li>Output formatters</li><li>Cross platform</li><li>Fully tested</li></ul><p><a title="unitbench" href="http://blog.quibb.org/unitbench">unitbench documentation</a></p><p><a title="unitbench pypi page" href="http://pypi.python.org/pypi/unitbench">unitbench pypi page (with downloads)</a></p><p><a title="unitbench source code" href="https://bitbucket.org/qbproger/unitbench">unitbench source code</a></p><p>I&#8217;d love to hear any feedback.  All comments are appreciated.  If you notice any bugs or weird behavior post a bug report to bitbucket or leave a comment here.  I&#8217;ll try to address it as soon as possible.  The same goes for feature requests.</p> ]]></content:encoded> <wfw:commentRss>http://blog.quibb.org/2011/03/unitbench-0-1-released/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Announcement: cppbench 0.2 released!</title><link>http://blog.quibb.org/2011/01/announcement-cppbench-0-2-released/</link> <comments>http://blog.quibb.org/2011/01/announcement-cppbench-0-2-released/#comments</comments> <pubDate>Wed, 05 Jan 2011 01:44:36 +0000</pubDate> <dc:creator>Joe</dc:creator> <category><![CDATA[Announcement]]></category> <category><![CDATA[benchmarks]]></category> <category><![CDATA[cppbench]]></category> <category><![CDATA[open source]]></category><guid isPermaLink="false">http://blog.quibb.org/?p=321</guid> <description><![CDATA[The second release of cppbench is here.  Cppbench is a open source C++ benchmark framework cppbench.  Someone on reddit suggested including user and system time.  After some research that seemed like a good idea, so here is a new release with some additional features. New Features include: Reporting of user and system time in addition [...]]]></description> <content:encoded><![CDATA[<p>The second release of <a title="cppbench" href="http://blog.quibb.org/cppbench/">cppbench</a> is here.  Cppbench is a open source C++ benchmark framework <a title="cppbench" href="http://blog.quibb.org/cppbench/">cppbench</a>.  Someone on <a title="reddit" href="http://www.reddit.com/r/cpp/comments/epxu5/cppbench_released_a_lightweight_benchmark/">reddit</a> suggested including user and system time.  After some research that seemed like a good idea, so here is a new release with some additional features.</p><p>New Features include:</p><ul><li>Reporting of user and system time in addition to wall clock time.<ul><li>User time is the amount of CPU time spent in user code.</li><li>System time is the amount of CPU time spent in the operating system kernel.</li></ul></li><li>XML output with all the information recorded by the system.</li><li>Now tested on mingw and cygwin.</li></ul><p>cppbench webpage: <a href="http://blog.quibb.org/cppbench/">http://blog.quibb.org/cppbench/</a></p><p>cppbench on bitbucket: <a href="https://bitbucket.org/qbproger/cppbench/overview">https://bitbucket.org/qbproger/cppbench/overview</a></p><p>cppbench api: <a href="http://blog.quibb.org/cppbench-api/">http://blog.quibb.org/cppbench-api/</a></p> ]]></content:encoded> <wfw:commentRss>http://blog.quibb.org/2011/01/announcement-cppbench-0-2-released/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Announcement: cppbench released!</title><link>http://blog.quibb.org/2010/12/announcement-cppbench-released/</link> <comments>http://blog.quibb.org/2010/12/announcement-cppbench-released/#comments</comments> <pubDate>Wed, 22 Dec 2010 14:30:06 +0000</pubDate> <dc:creator>Joe</dc:creator> <category><![CDATA[Announcement]]></category> <category><![CDATA[C++]]></category> <category><![CDATA[benchmarks]]></category> <category><![CDATA[cppbench]]></category> <category><![CDATA[open source]]></category><guid isPermaLink="false">http://blog.quibb.org/?p=308</guid> <description><![CDATA[While working on the sqlite benchmarks, I ended up writing a lightweight C++ benchmark framework to make the task easier.  I thought other people might find it useful too.  Then to prepare it for other people to use I wrote documentation and did some cleanup. Some of the features include: Simplified BSD License High fidelity [...]]]></description> <content:encoded><![CDATA[<p>While working on the sqlite benchmarks, I ended up writing a lightweight C++ benchmark framework to make the task easier.  I thought other people might find it useful too.  Then to prepare it for other people to use I wrote documentation and did some cleanup.</p><p>Some of the features include:</p><ul><li>Simplified BSD License</li><li>High fidelity stopwatch</li><li>Output formatters</li><li>Cross platform</li></ul><p>For a more complete list of features see the <a title="cppbench" href="http://blog.quibb.org/cppbench">cppbench</a> webpage.  With the mindset &#8220;release early, release often&#8221; here it is:</p><p>Webpage: <a title="http://blog.quibb.org/cppbench" href="http://blog.quibb.org/cppbench">http://blog.quibb.org/cppbench</a></p><p>Bitbucket: <a href="https://bitbucket.org/qbproger/cppbench/overview">https://bitbucket.org/qbproger/cppbench/overview</a></p><p>API: <a href="http://blog.quibb.org/cppbench-api/">http://blog.quibb.org/cppbench-api/</a></p><p>This being the first open source project I&#8217;ve released, any feedback is appreciated.</p> ]]></content:encoded> <wfw:commentRss>http://blog.quibb.org/2010/12/announcement-cppbench-released/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Some SQLite 3.7 Benchmarks</title><link>http://blog.quibb.org/2010/10/some-sqlite-3-7-benchmarks/</link> <comments>http://blog.quibb.org/2010/10/some-sqlite-3-7-benchmarks/#comments</comments> <pubDate>Thu, 14 Oct 2010 13:00:01 +0000</pubDate> <dc:creator>Joe</dc:creator> <category><![CDATA[C++]]></category> <category><![CDATA[benchmarks]]></category> <category><![CDATA[sqlite]]></category><guid isPermaLink="false">http://blog.quibb.org/?p=259</guid> <description><![CDATA[Since I wrote the benchmarks for insertions in my last post, SQLite 3.7 has been released. I figured it&#8217;d be interesting to see if 3.7 changed the situation at all. Prepared Statements The specific versions compared here are 3.6.23.1 and 3.7.3.  I ran the prepared statements benchmark as is without changing any source code.  Both [...]]]></description> <content:encoded><![CDATA[<p>Since I wrote the benchmarks for insertions in my <a title="last post" href="http://blog.quibb.org/2010/08/fast-bulk-inserts-into-sqlite/">last post</a>, <a title="SQLite" href="http://sqlite.org/">SQLite</a> 3.7 has been released.  I figured it&#8217;d be interesting to see if 3.7 changed the situation at all.</p><h2>Prepared Statements</h2><p>The specific versions compared here are 3.6.23.1 and 3.7.3.   I ran the  prepared statements benchmark as is without changing any source code.  Both are using a rollback journal in this case.</p><div id="attachment_263" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.quibb.org/wp-content/uploads/2010/10/prepared_runtime.png"><img class="size-medium wp-image-263" title="Prepared Statements Runtime" src="http://blog.quibb.org/wp-content/uploads/2010/10/prepared_runtime-300x188.png" alt="" width="300" height="188" /></a><p class="wp-caption-text">Prepared Statements Runtime in Seconds</p></div><div id="attachment_264" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.quibb.org/wp-content/uploads/2010/10/prepared_ips.png"><img class="size-medium wp-image-264" title="Prepared Statements Inserts Per Second" src="http://blog.quibb.org/wp-content/uploads/2010/10/prepared_ips-300x188.png" alt="Prepared Statements Inserts Per Second" width="300" height="188" /></a><p class="wp-caption-text">Prepared Statements Inserts Per Second</p></div><p>As you can see, the new version of SQLite definitely provides better performance.  There is a speedup of about 3 seconds.</p><h2>Journal Mode Comparison</h2><p>One of the main features SQLite 3.7 added was <a title="Write Ahead Logging" href="http://www.sqlite.org/wal.html">Write Ahead Logging (WAL)</a>.   The main advantage of write-ahead logging is it allows more concurrent  access to the database than a rollback journal.  These benchmarks don&#8217;t  show the true potential of write-ahead logging.  The benchmarks  are single threaded, and they insert a large amount of data in  one transaction.  It&#8217;s listed as a disadvantage that large transactions  can be slow with write-ahead logging, even having the potential to  return an error.  I wanted to evaluate write-ahead logging as a drop in  replacement.</p><p>I ran the prepared statements benchmark with the default, memory, and wal settings.  I also ran each setting with and without <a title="synchronous" href="http://sqlite.org/pragma.html#pragma_synchronous">synchronous</a> on.  The synchronous setting controls how often sqlite waits for data to be physically written to the hard disk.  The default setting is full, which is the safest because it waits for data to be written to the hard disk most frequently.  This is compared to synchronous being off, which lets the operating system decide when information should be written to the hard disk.  In this case if there is a software crash, it&#8217;s more likely the database could become corrupt.</p><div id="attachment_265" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.quibb.org/wp-content/uploads/2010/10/journal_runtime.png"><img class="size-medium wp-image-265" title="Journal Mode Runtime Comparison" src="http://blog.quibb.org/wp-content/uploads/2010/10/journal_runtime-300x155.png" alt="Journal Mode Runtime Comparison" width="300" height="155" /></a><p class="wp-caption-text">Journal Mode Runtime Comparison</p></div><div id="attachment_266" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.quibb.org/wp-content/uploads/2010/10/journal_ips.png"><img class="size-medium wp-image-266" title="Journal Mode Inserts Per Second" src="http://blog.quibb.org/wp-content/uploads/2010/10/journal_ips-300x154.png" alt="Journal Mode Inserts Per Second" width="300" height="154" /></a><p class="wp-caption-text">Journal Mode Inserts Per Second</p></div><p>Up until about 100,000 insertions all the journal modes and synchronous settings are about even.  After 100,000, the insertion benchmarks with synchronous off are faster than their default synchronous counterparts.  Journal mode set to memory and synchronous off offered the best performance for this benchmark.</p> ]]></content:encoded> <wfw:commentRss>http://blog.quibb.org/2010/10/some-sqlite-3-7-benchmarks/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Fast Bulk Inserts into SQLite</title><link>http://blog.quibb.org/2010/08/fast-bulk-inserts-into-sqlite/</link> <comments>http://blog.quibb.org/2010/08/fast-bulk-inserts-into-sqlite/#comments</comments> <pubDate>Tue, 10 Aug 2010 14:11:56 +0000</pubDate> <dc:creator>Joe</dc:creator> <category><![CDATA[C++]]></category> <category><![CDATA[benchmarks]]></category> <category><![CDATA[optimization]]></category> <category><![CDATA[sqlite]]></category><guid isPermaLink="false">http://blog.quibb.org/?p=219</guid> <description><![CDATA[Background Sometimes it’s necessary to get information into a database quickly. SQLite is a light weight database engine that can be easily embedded in applications. This will cover the process of optimizing bulk inserts into an SQLite database. While this article focuses on SQLite some of the techniques shown here will apply to other databases. [...]]]></description> <content:encoded><![CDATA[<h2>Background</h2><p>Sometimes it’s necessary to get information into a database quickly. <a title="SQLite" href="http://sqlite.org/"> SQLite</a> is a light weight database engine that can be easily embedded in applications.  This will cover the process of optimizing bulk inserts into an SQLite database.  While this article focuses on SQLite some of the techniques shown here will apply to other databases.</p><p>All of the following examples insert data into the same table.  It&#8217;s a table where an ID is the first element followed by three FLOAT values, and then follow by three INTEGER values.  You&#8217;ll notice the getDouble() and getInt() functions.  They return doubles and ints in a predictable manner.  I didn&#8217;t use random data because different values could potentially add variability to the benchmarks at the end.</p><h2>Naive Inserts</h2><p>This is the most basic way to insert information into SQLite.  It simply calls <a title="sqlite3_exec" href="http://www.sqlite.org/c3ref/exec.html">sqlite3_exec</a> for each insert in the database.</p><div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">char</span> buffer<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">300</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> mVal<span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000dd;">sprintf</span><span style="color: #008000;">&#40;</span>buffer, <span style="color: #FF0000;">&quot;INSERT INTO example VALUES ('%s', %lf, %lf, %lf, %d, %d, %d)&quot;</span>,
            getID<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">c_str</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>,
            getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, buffer, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div><h2>Inserts within a Transaction</h2><p>A transaction is a way to group SQL statements together.  If an error is encountered the ON CONFLICT statement can be used to handle that to your liking.  Nothing will be written to the SQLite database until either END or COMMIT is encountered to signify the transaction should be closed and written.</p><div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> errorMessage<span style="color: #008080;">;</span>
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;BEGIN TRANSACTION&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">char</span> buffer<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">300</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> mVal<span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000dd;">sprintf</span><span style="color: #008000;">&#40;</span>buffer, <span style="color: #FF0000;">&quot;INSERT INTO example VALUES ('%s', %lf, %lf, %lf, %d, %d, %d)&quot;</span>,
            getID<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">c_str</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>,
            getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, buffer, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;COMMIT TRANSACTION&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div><h2>PRAGMA Statements</h2><p><a title="PRAGMA" href="http://sqlite.org/pragma.html">PRAGMA</a> statements control the behavior of SQLite as a whole.  They can be used to tweak options such as how often the data is flushed to disk of the size of the cache.  These are some that are commonly used for performance.  The SQLite documentation fully explains what they do and the implications of using them.  For example, synchronous off will cause SQLite to not stop and wait for the data to get written to the hard drive.  In the event of a crash or power failure, it is more likely the database could be corrupted.</p><div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;PRAGMA synchronous=OFF&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;PRAGMA count_changes=OFF&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;PRAGMA journal_mode=MEMORY&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;PRAGMA temp_store=MEMORY&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div><h2>Prepared Statements</h2><p><a title="Prepared Statements" href="http://sqlite.org/c3ref/prepare.html">Prepared statements</a> are the recommended way of sending queries to SQLite.   Rather than parsing the statement over and over again, the parser only needs to be run once on the statement.  According to the documentation, sqlite3_exec is a convenience function  that calls sqlite3_prepare_v2(), sqlite3_step(), and then  sqlite3_finalize().  In my opinion, the documentation should more explicitly say that prepared statements are the preferred query method.  sqlite3_exec() should only be used for one time use queries.</p><div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> errorMessage<span style="color: #008080;">;</span>
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;BEGIN TRANSACTION&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">char</span> buffer<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;INSERT INTO example VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)&quot;</span><span style="color: #008080;">;</span>
sqlite3_stmt<span style="color: #000040;">*</span> stmt<span style="color: #008080;">;</span>
sqlite3_prepare_v2<span style="color: #008000;">&#40;</span>mDb, buffer, <span style="color: #0000dd;">strlen</span><span style="color: #008000;">&#40;</span>buffer<span style="color: #008000;">&#41;</span>, <span style="color: #000040;">&amp;</span>stmt, <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> mVal<span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> id <span style="color: #000080;">=</span> getID<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_text<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">1</span>, id.<span style="color: #007788;">c_str</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, id.<span style="color: #007788;">size</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, SQLITE_STATIC<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_double<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">2</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_double<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">3</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_double<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">4</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_int<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">5</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_int<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">6</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_int<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">7</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>sqlite3_step<span style="color: #008000;">&#40;</span>stmt<span style="color: #008000;">&#41;</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> SQLITE_DONE<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Commit Failed!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    sqlite3_reset<span style="color: #008000;">&#40;</span>stmt<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;COMMIT TRANSACTION&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
sqlite3_finalize<span style="color: #008000;">&#40;</span>stmt<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div><h2>Storing Data as Binary Blob</h2><p>Up until now, most of the optimizations have been pretty much the standard advice that you get when looking into bulk insert optimization.  If you’re not running queries on some of the data, it’s possible to convert it to binary and store it as a blob.  While it’s not advised to just throw everything into a blob and put it in the database, putting data that would be pulled and used together into a binary blob can make sense in some situations.</p><p>For example, if you have a point class (x, y, z) with REAL values, it might make sense to store them in a blob rather than three separate fields in row.  That’s only if you don’t need to make queries on the data though.  The benefit of this technique increases as more fields are converted into larger blobs.</p><div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> errorMessage<span style="color: #008080;">;</span>
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;BEGIN TRANSACTION&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">char</span> buffer<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;INSERT INTO example VALUES (?1, ?2, ?3, ?4, ?5)&quot;</span><span style="color: #008080;">;</span>
sqlite3_stmt<span style="color: #000040;">*</span> stmt<span style="color: #008080;">;</span>
sqlite3_prepare_v2<span style="color: #008000;">&#40;</span>mDb, buffer, <span style="color: #0000dd;">strlen</span><span style="color: #008000;">&#40;</span>buffer<span style="color: #008000;">&#41;</span>, <span style="color: #000040;">&amp;</span>stmt, <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> mVal<span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> id <span style="color: #000080;">=</span> getID<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_text<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">1</span>, id.<span style="color: #007788;">c_str</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, id.<span style="color: #007788;">size</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, SQLITE_STATIC<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">char</span> dblBuffer<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">24</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">double</span> d<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #008000;">&#123;</span>getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">memcpy</span><span style="color: #008000;">&#40;</span>dblBuffer, <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">&amp;</span>d, <span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span>d<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_blob<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">2</span>, dblBuffer, <span style="color: #0000dd;">24</span>, SQLITE_STATIC<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_int<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">3</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_int<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">4</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_int<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">5</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">int</span> retVal <span style="color: #000080;">=</span> sqlite3_step<span style="color: #008000;">&#40;</span>stmt<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>retVal <span style="color: #000040;">!</span><span style="color: #000080;">=</span> SQLITE_DONE<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Commit Failed! %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, retVal<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    sqlite3_reset<span style="color: #008000;">&#40;</span>stmt<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;COMMIT TRANSACTION&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
sqlite3_finalize<span style="color: #008000;">&#40;</span>stmt<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div><p>Note: I just used memcpy here, but this would have issues going between big and little endian systems.  If that’s necessary, it would be a good idea to serialize the data using a serialization library (ie &#8211; <a title="protocol buffers" href="http://code.google.com/apis/protocolbuffers/docs/overview.html">protocol buffers</a> or <a title="MsgPack" href="http://msgpack.org/">msgpack</a>).</p><h2>Performance</h2><p>I ran benchmarks to test the performance of each method of inserting data.  Take note that the x axis does not scale linearly, it most closely matches a logarithmic scale.  The inserts per second graph was obtained by taking the number of inserts and dividing it by the total runtime.</p><div id="attachment_238" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.quibb.org/wp-content/uploads/2010/07/bulk_insert_runtime.png"><img class="size-medium wp-image-238 " title="SQLite Bulk Insert Runtime" src="http://blog.quibb.org/wp-content/uploads/2010/07/bulk_insert_runtime-300x182.png" alt="SQLite Bulk Insert Runtime" width="300" height="182" /></a><p class="wp-caption-text">SQLite Build Insert Runtime in Seconds</p></div><p style="text-align: center;"><div id="attachment_239" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.quibb.org/wp-content/uploads/2010/07/inserts_per_second.png"><img class="size-medium wp-image-239" title="Inserts Per Second" src="http://blog.quibb.org/wp-content/uploads/2010/07/inserts_per_second-300x182.png" alt="Inserts Per Second" width="300" height="182" /></a><p class="wp-caption-text">SQLite Inserts Per Second</p></div><p style="text-align: center;"><a href="http://blog.quibb.org/wp-content/uploads/2010/07/inserts_per_second.png"></a></p><p style="text-align: left;">After running the first benchmark, I wanted to show how storing data in binary can make a difference.  I ran it again, but instead of storing only three doubles, I stored 24 doubles.  I assumed order mattered, so for the benchmark that is not stored in a binary blob, I made a separate table with ID and order columns.  This way both versions captured the same information.</p><p style="text-align: left;"><div id="attachment_242" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.quibb.org/wp-content/uploads/2010/07/big_insert_runtime.png"><img class="size-medium wp-image-242" title="Big Insert Runtime" src="http://blog.quibb.org/wp-content/uploads/2010/07/big_insert_runtime-300x182.png" alt="Big Insert Runtime" width="300" height="182" /></a><p class="wp-caption-text">Big Insert Runtime in Seconds</p></div><div id="attachment_244" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.quibb.org/wp-content/uploads/2010/07/big_insert_per_second.png"><img class="size-medium wp-image-244" title="Big Inserts Per Second" src="http://blog.quibb.org/wp-content/uploads/2010/07/big_insert_per_second-300x181.png" alt="Big Inserts Per Second" width="300" height="181" /></a><p class="wp-caption-text">Big Inserts Per Second</p></div><p>Good luck with your database inserts.</p><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow: hidden;"><h1 id="internal-source-marker_0.4793873936321398"><span style="font-size: 24pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Fast Bulk Inserts into SQLite</span></h1><h2><span style="font-size: 18pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Background</span></h2><p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Sometimes it’s necessary to get information into a database quickly.  SQLite[</span><a href="http://sqlite.org/"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">http://sqlite.org/</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">]  is a light weight database engine that can be easily embedded in  applications.  This will cover the process of optimizing bulk inserts  into an SQLite database.  While this article focuses on SQLite some of  the techniques shown here will apply to other databases.</span></p><h2><span style="font-size: 18pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Naive Inserts</span></h2><p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">This is the most basic way to insert information into SQLite.  It simply calls sqlite3_exec[</span><a href="http://www.sqlite.org/c3ref/exec.html"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">http://www.sqlite.org/c3ref/exec.html</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">] for each insert in the database.</span><br /> <span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[insert code here]</span></p><p><span style="font-size: 18pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Inserts within a Transaction</span><br /> <span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">A  transaction is a way to group SQL statements together.  If an error is  encountered the ON CONFLICT statement can be used to handle that to your  liking.  Nothing will be written to the SQLite database until either  END or COMMIT is encountered to signify the transaction should be  written and closed.</span><br /> <span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[insert code here]</span></p><h2><span style="font-size: 18pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">PRAGMA Statements</span></h2><p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">PRAGMA statements[</span><a href="http://sqlite.org/pragma.html"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">http://sqlite.org/pragma.html</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">]  control the behavior of SQLite as a whole.  They can be used to tweak  options such as how often the data is flushed to disk of the size of the  cache.</span><br /> <span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[insert code here]</span></p><h2><span style="font-size: 18pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Prepared Statements</span></h2><p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Prepared statements[</span><a href="http://sqlite.org/c3ref/prepare.html"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">http://sqlite.org/c3ref/prepare.html</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">]  are the recommended way of sending queries to SQLite.  Rather than  parsing the statement over and over again, the parser only needs to be  run once on the statement.  In all honesty, the documentation for  sqlite3_exec should say not to use it at all in favor of prepared  statements.  They are not only faster on inserts, but across the board  for all SQL statements.</span><br /> <span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[insert cod here]</span></p><h2><span style="font-size: 18pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Storing Data as Binary Blob</span></h2><p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Up  until now, most of the optimizations have been pretty much the standard  advice that you get when looking into bulk insert optimization.  If  you’re not running queries on some of the data, it’s possible to convert  it to binary and store it as a blob.  While it’s not advised to just  throw everything into a blob and put it in the database, putting data  that would be pulled and used together into a binary blob can make sense  in some situations.</span><br /> <span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">For  example, if you have a point class (x, y, z) with REAL values, it might  make sense to store them in a blob rather than three separate fields in  row.  That’s only if you don’t need to make queries on the data though.   The benefits of this technique increase as more fields are converted  into larger blobs.</span><br /> <span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[insert code here]</span><br /> <span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Note:  I just do a memcpy here, but this would have issues going between big  and little endian systems.  If that’s necessary, it would be a good idea  to serialize the data using a serialization library (ie &#8211; protocol  buffers[http://code.google.com/apis/protocolbuffers/docs/overview.html],  msgpack[http://msgpack.org/],  thrift[http://incubator.apache.org/thrift/]).</span></p><h2><span style="font-size: 18pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Performance</span></h2><p>Fast Bulk Inserts into SQLite</p><p>Background</p><p>Sometimes it’s necessary to get information into a database quickly.  SQLite[http://sqlite.org/] is a light weight database engine that can be easily embedded in applications.  This will cover the process of optimizing bulk inserts into an SQLite database.  While this article focuses on SQLite some of the techniques shown here will apply to other databases.</p><p>Naive Inserts</p><p>This is the most basic way to insert information into SQLite.  It simply calls sqlite3_exec[http://www.sqlite.org/c3ref/exec.html] for each insert in the database.</p><p>[insert code here]</p><p>Inserts within a Transaction</p><p>A transaction is a way to group SQL statements together.  If an error is encountered the ON CONFLICT statement can be used to handle that to your liking.  Nothing will be written to the SQLite database until either END or COMMIT is encountered to signify the transaction should be written and closed.</p><p>[insert code here]</p><p>PRAGMA Statements</p><p>PRAGMA statements[http://sqlite.org/pragma.html] control the behavior of SQLite as a whole.  They can be used to tweak options such as how often the data is flushed to disk of the size of the cache.</p><p>[insert code here]</p><p>Prepared Statements</p><p>Prepared statements[http://sqlite.org/c3ref/prepare.html] are the recommended way of sending queries to SQLite.  Rather than parsing the statement over and over again, the parser only needs to be run once on the statement.  In all honesty, the documentation for sqlite3_exec should say not to use it at all in favor of prepared statements.  They are not only faster on inserts, but across the board for all SQL statements.</p><p>[insert cod here]</p><p>Storing Data as Binary Blob</p><p>Up until now, most of the optimizations have been pretty much the standard advice that you get when looking into bulk insert optimization.  If you’re not running queries on some of the data, it’s possible to convert it to binary and store it as a blob.  While it’s not advised to just throw everything into a blob and put it in the database, putting data that would be pulled and used together into a binary blob can make sense in some situations.</p><p>For example, if you have a point class (x, y, z) with REAL values, it might make sense to store them in a blob rather than three separate fields in row.  That’s only if you don’t need to make queries on the data though.  The benefits of this technique increase as more fields are converted into larger blobs.</p><p>[insert code here]</p><p>Note: I just do a memcpy here, but this would have issues going between big and little endian systems.  If that’s necessary, it would be a good idea to serialize the data using a serialization library (ie &#8211; protocol buffers[http://code.google.com/apis/protocolbuffers/docs/overview.html], msgpack[http://msgpack.org/], thrift[http://incubator.apache.org/thrift/]).</p><p>Performance</p></div><p><span id="more-219"></span></p> ]]></content:encoded> <wfw:commentRss>http://blog.quibb.org/2010/08/fast-bulk-inserts-into-sqlite/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk (enhanced)
Database Caching 2/26 queries in 0.007 seconds using disk
Object Caching 526/569 objects using disk

Served from: blog.quibb.org @ 2012-02-05 12:16:00 -->
