<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>the lazy hacker blog</title>
  <id>http://127.0.0.1</id>
  <updated>2010-07-15</updated>
  <author>
    <name>bharanee</name>
  </author>
  <entry>
    <title>Documenting dbic++</title>
    <link rel="alternate" href="http://127.0.0.1/2010/08/18/documenting-dbic/"/>
    <id>http://127.0.0.1/2010/08/18/documenting-dbic/</id>
    <published>2010-08-18</published>
    <updated>2010-08-18</updated>
    <author>
      <name>bharanee</name>
    </author>
    <summary type="html">&lt;p&gt;I had a look at &lt;a href="http://www.naturaldocs.org"&gt;naturaldocs&lt;/a&gt; and decided to
document &lt;a href="http://www.github.com/deepfryed/dbicpp"&gt;dbic++&lt;/a&gt;. I don&amp;rsquo;t think
it was a brilliant idea given I started it with a glass of scotch by my&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;I had a look at &lt;a href="http://www.naturaldocs.org"&gt;naturaldocs&lt;/a&gt; and decided to
document &lt;a href="http://www.github.com/deepfryed/dbicpp"&gt;dbic++&lt;/a&gt;. I don&amp;rsquo;t think
it was a brilliant idea given I started it with a glass of scotch by my
side.&lt;/p&gt;

&lt;p&gt;I may have to proof read in the morning given its almost 11pm here. But
for rest of you night owls, here it is &amp;ndash; &lt;a href="http://dbicpp.fried.in/"&gt;dbic++ docs&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>An object mapper that's uber fast and lean.</title>
    <link rel="alternate" href="http://127.0.0.1/2010/08/12/an-object-mapper-thats-uber-fast-and-lean/"/>
    <id>http://127.0.0.1/2010/08/12/an-object-mapper-thats-uber-fast-and-lean/</id>
    <published>2010-08-12</published>
    <updated>2010-08-12</updated>
    <author>
      <name>bharanee</name>
    </author>
    <summary type="html">&lt;br/&gt;


&lt;p&gt;&lt;a href="http://www.twitter.com/shanehanna"&gt;@shanehanna&lt;/a&gt; recently released a first cut
of the Swift Object Mapper to &lt;a href="http://www.rubygems.org/gems/swift"&gt;rubygems&lt;/a&gt;&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;br/&gt;


&lt;p&gt;&lt;a href="http://www.twitter.com/shanehanna"&gt;@shanehanna&lt;/a&gt; recently released a first cut
of the Swift Object Mapper to &lt;a href="http://www.rubygems.org/gems/swift"&gt;rubygems&lt;/a&gt;.
&lt;a href="http://www.github.com/shanna/swift"&gt;Swift&lt;/a&gt; has come along a fair bit since
we started hacking on it as a hobby to see if we can put to rest the criticism
that ruby is slow and takes up too much memory.&lt;/p&gt;

&lt;p&gt;I ran some benchmarks this morning and found it to be &lt;tt&gt;4x&lt;/tt&gt; fast on average compared
to &lt;tt&gt;ActiveRecord&lt;/tt&gt; and &lt;tt&gt;DataMapper&lt;/tt&gt;. It uses considerably less memory (&lt;tt&gt;90%&lt;/tt&gt; less)
as well. If you are inserting a lot of records, you should consider using the
&lt;tt&gt;Swift::Adapter#write&lt;/tt&gt; method, as it can lead to tremendous speedup (&lt;tt&gt;~50-80x&lt;/tt&gt;)
and memory savings.&lt;/p&gt;

&lt;p&gt;Why reinvent the wheel you ask ? Take a look at the numbers below and you will
understand. &lt;tt&gt;ActiveRecord&lt;/tt&gt; and &lt;tt&gt;DataMapper&lt;/tt&gt; come with a lot of features and hence
some pretty heavy baggage. We realized that most of the time, all we used them for
was mapping properties to fields in the database and some basic validations.
We realized that we could do this in a much more simpler fashion.&lt;/p&gt;

&lt;br/&gt;


&lt;h3&gt;More coming soon &amp;hellip;&lt;/h3&gt;

&lt;p&gt;Swift is not as feature rich as &lt;tt&gt;ActiveRecord&lt;/tt&gt; or &lt;tt&gt;DataMapper&lt;/tt&gt;, it was meant to be
a simple and thin abstraction. We&amp;rsquo;re planning on working on swift-more soon
which would have a ton of goodies including validations, associations etc.&lt;/p&gt;

&lt;p&gt;Also planned are adapters for &lt;tt&gt;SphinxSearch&lt;/tt&gt; and &lt;tt&gt;Mongo&lt;/tt&gt;. &lt;tt&gt;SphinxSearch 1.10&lt;/tt&gt; allows
you to store fields directly in addition to making them searchable. We plan to
either use the real-time indexing feature or &lt;tt&gt;xmlpipe2&lt;/tt&gt; to persist objects in sphinx
directly.&lt;/p&gt;

&lt;br/&gt;


&lt;h3&gt;The benchmarks&lt;/h3&gt;

&lt;p&gt;The bechmark code for each ORM,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates 10,000 records at the start.&lt;/li&gt;
&lt;li&gt;Selects all the records from the database and goes through the results once.&lt;/li&gt;
&lt;li&gt;Selects all the records and updates the fields once for each record.&lt;/li&gt;
&lt;li&gt;GC is disabled to measure the actual memory footprint of each test run.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;ActiveRecord&lt;/tt&gt; uses &lt;tt&gt;mysql2&lt;/tt&gt; and &lt;tt&gt;pg&lt;/tt&gt; gems and
&lt;tt&gt;Swift&lt;/tt&gt; uses bindings to &lt;tt&gt;dbic++&lt;/tt&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;You can clone the &lt;a href="http://github.com/shanna/swift/blob/master/benchmarks/simple.rb"&gt;repo&lt;/a&gt;, run the
tests and see for yourself.&lt;/p&gt;

&lt;h4&gt;MySQL&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;benchmark       sys          user        total       rss
dm #create      0.360000     3.650000    4.010000    227.14m
dm #select      0.140000     1.880000    2.020000    128.94m
dm #update      0.710000     8.330000    9.040000    593.20m

ar #create      0.570000     5.360000    5.930000    304.77m
ar #select      0.020000     0.170000    0.190000    22.92m
ar #update      0.560000     5.710000    6.270000    322.95m

swift #create   0.310000     0.680000    0.990000    30.61m
swift #select   0.000000     0.100000    0.100000    9.32m
swift #update   0.140000     0.660000    0.800000    32.26m
swift #write    0.000000     0.070000    0.070000    6.79m
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;PostgreSQL&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;benchmark       sys          user        total       rss
dm #create      0.360000     3.560000    3.920000    245.34m
dm #select      0.110000     1.910000    2.020000    129.11m
dm #update      0.590000     7.910000    8.500000    604.77m

ar #create      1.030000     7.100000    8.130000    367.80m
ar #select      0.030000     0.320000    0.350000    38.82m
ar #update      0.800000     6.630000    7.430000    361.91m

swift #create   0.220000     0.680000    0.900000    30.60m
swift #select   0.010000     0.070000    0.080000    9.82m
swift #update   0.100000     0.890000    0.990000    32.66m
swift #write    0.000000     0.080000    0.080000    7.30m
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  <entry>
    <title>Bulk loading data into MySQL</title>
    <link rel="alternate" href="http://127.0.0.1/2010/07/26/bulk-loading-data-into-mysql/"/>
    <id>http://127.0.0.1/2010/07/26/bulk-loading-data-into-mysql/</id>
    <published>2010-07-26</published>
    <updated>2010-07-26</updated>
    <author>
      <name>bharanee</name>
    </author>
    <summary type="html">&lt;p&gt;During a casual conversation last week with a friend, we happened to
talk about how you can bulk load data data in PostgreSQL without writing
to temporary files via the PQputCopyData API&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;During a casual conversation last week with a friend, we happened to
talk about how you can bulk load data data in PostgreSQL without writing
to temporary files via the PQputCopyData API.&lt;/p&gt;

&lt;p&gt;The MySQL client API does not have an equivalent way of streaming data
right from your program/script. So I started thinking about how I can
do this in MySQL. MySQL C API does allow you to specify your own &lt;a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-set-local-infile-handler.html"&gt;infile handlers&lt;/a&gt; but it seemed unnecessarily complicated.&lt;/p&gt;

&lt;p&gt;&lt;del&gt;
A few drinkies later, I tripped on a neat solution. &lt;em&gt;named pipes&lt;/em&gt; &amp;ndash; et voil&#224;!&lt;/p&gt;

&lt;p&gt;So all I had to do was create a named pipe, fire up a thread and stream the
data to the pipe in that thread and let the mysql client library read from
it. No temporary files, no cleanups (except for unlinking the FIFO file).
&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;In principle this is same as&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkfifo -m0666 /tmp/somefile.fifo
zcat users.gz &amp;gt; /tmp/somefile.fifo &amp;amp;
mysql -uroot mytestdb -e "load data local infile '/tmp/somefile.fifo' into table users;"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;UPDATE&lt;/b&gt; &lt;em&gt;Although named pipes worked like a charm it started to cause issues with
threaded applications in ruby. So I had to implement custom &lt;em&gt;infile&lt;/em&gt; handlers for dbic++ which
was a bit more code but works like a charm.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But a nice little api around this helps!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'etc'
require 'swift'
require 'stringio'

data = StringIO.new "sally\tsally@local\njerry\tjerry@local\n"

Swift.setup :default, Swift::DB::Mysql, user: Etc.getlogin, db: 'swift'

Swift.db do |db|
  db.execute 'drop table if exists users'
  db.execute 'create table users (id serial, name text, email text, primary key(id))'
  db.write   'users', %w{name email}, data
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The block can stream data from anywhere, file, network etc and straight into MySQL. You just have to
make sure you do it in batches of reasonable size to avoid MySQL writing too much to its binary log
(WAL in case of PosgreSQL) in case you have to rollback.&lt;/p&gt;

&lt;p&gt;Grab the latest &lt;a href="http://github.com/deepfryed/dbicpp"&gt;dbic++&lt;/a&gt; and &lt;a href="http://github.com/shanna/swift"&gt;swift&lt;/a&gt;,
have fun!&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Allow me to introduce dbic++</title>
    <link rel="alternate" href="http://127.0.0.1/2010/07/18/allow-me-to-introduce-dbic/"/>
    <id>http://127.0.0.1/2010/07/18/allow-me-to-introduce-dbic/</id>
    <published>2010-07-18</published>
    <updated>2010-07-18</updated>
    <author>
      <name>bharanee</name>
    </author>
    <summary type="html">&lt;p&gt;As &lt;a href="/2010/07/16/how-fast-can-you-go-"&gt;promised&lt;/a&gt;, I give thee &lt;a href="http://github.com/deepfryed/dbicpp"&gt;&lt;em&gt;dbic++&lt;/em&gt;&lt;/a&gt;,
a kick ass database abstraction. Clone away!&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;As &lt;a href="/2010/07/16/how-fast-can-you-go-"&gt;promised&lt;/a&gt;, I give thee &lt;a href="http://github.com/deepfryed/dbicpp"&gt;&lt;em&gt;dbic++&lt;/em&gt;&lt;/a&gt;,
a kick ass database abstraction. Clone away!&lt;/p&gt;

&lt;p&gt;Mind you it&amp;rsquo;s still under heavy development, so don&amp;rsquo;t use this on any critical production code.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>How fast can you go ?</title>
    <link rel="alternate" href="http://127.0.0.1/2010/07/16/how-fast-can-you-go-/"/>
    <id>http://127.0.0.1/2010/07/16/how-fast-can-you-go-/</id>
    <published>2010-07-16</published>
    <updated>2010-07-16</updated>
    <author>
      <name>bharanee</name>
    </author>
    <summary type="html">&lt;p&gt;&lt;a href="/2010/07/15/a-clean-and-simple-database-api"&gt;I started writing&lt;/a&gt; a database abstraction library in C++ (&lt;em&gt;libdbic++&lt;/em&gt;)
to see if I can write something simple and fast that I can use at work. I was surprised at how fast it did manage to go&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;&lt;a href="/2010/07/15/a-clean-and-simple-database-api"&gt;I started writing&lt;/a&gt; a database abstraction library in C++ (&lt;em&gt;libdbic++&lt;/em&gt;)
to see if I can write something simple and fast that I can use at work. I was surprised at how fast it did manage to go.&lt;/p&gt;

&lt;p&gt;I also wrote ruby bindings (&lt;em&gt;swift&lt;/em&gt;) with help from @shanehanna. This makes it easier to start
writing apps in ruby and then switch to C++ if performance becomes a bigger priority. A single API that
makes it easy to transition from ruby to C++ was the goal.&lt;/p&gt;

&lt;p&gt;The performance numbers for retrieving 250,000 records of approximately 64 bytes each was quite encouraging.
We intend to hack away at this until we have something nice and polished.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mysql
=====
                                     user     system      total        real
 ruby: do                        3.350000   0.110000   3.460000 (  4.431064)
 ruby: swift                     1.080000   0.110000   1.190000 (  1.905136)
 c: libmysqlclient               0.000000   0.000000   0.230000 (  0.933122)
 c++: libdbic++                  0.000000   0.010000   0.510000 (  1.163342)
 ruby: mysql2                    2.150000   0.040000   2.190000 (  3.155557)
 c++: libmysql++                 0.000000   0.000000   0.480000 (  1.437604)

postgresql
==========
                                     user     system      total        real
 ruby: do                        3.470000   0.130000   3.600000 (  4.583538)
 ruby: swift                     1.300000   0.070000   1.370000 (  2.010762)
 ruby: libpq                     1.800000   0.120000   1.920000 (  2.815204)
 c++: libdbic++                  0.000000   0.000000   0.560000 (  1.336096)
 c: libpq                        0.010000   0.000000   0.510000 (  1.085639)
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  <entry>
    <title>A clean and simple database api</title>
    <link rel="alternate" href="http://127.0.0.1/2010/07/15/a-clean-and-simple-database-api/"/>
    <id>http://127.0.0.1/2010/07/15/a-clean-and-simple-database-api/</id>
    <published>2010-07-15</published>
    <updated>2010-07-15</updated>
    <author>
      <name>bharanee</name>
    </author>
    <summary type="html">&lt;p&gt;Recently, I started looking for a simple C/C++ database abstraction layer with a nice and simple API. The best I came across was &lt;a href="http://libdbi.sourceforge.net/"&gt;&lt;em&gt;libdbi&lt;/em&gt;&lt;/a&gt;&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;Recently, I started looking for a simple C/C++ database abstraction layer with a nice and simple API. The best I came across was &lt;a href="http://libdbi.sourceforge.net/"&gt;&lt;em&gt;libdbi&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I wanted something that did the following,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PostgreSQL and MySQL support &amp;ndash; because those are the 2 main databases we use at work.&lt;/li&gt;
&lt;li&gt;Transaction and Savepoint support.&lt;/li&gt;
&lt;li&gt;Support for non-blocking async calls.&lt;/li&gt;
&lt;li&gt;Support prepared statements.&lt;/li&gt;
&lt;li&gt;Do all this in a fast and simple fashion.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Unfortunately libdbi did not have some features such as support for prepared statements and support for asynchronous access. Coming from years of Perl development, I expected something along the lines of DBI and was disappointed.&lt;/p&gt;

&lt;p&gt;I wanted to try writing something over the next weekend to see if I could come up with something simple and fast that works with &lt;em&gt;PostgreSQL&lt;/em&gt; and &lt;em&gt;MySQL&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;After a few weeks of  toying around, I ended up with &lt;em&gt;dbic++&lt;/em&gt;. What started as a learning exercise ended up becoming a pet project that started to look better than many of the existing open source libraries. It also ended up outperforming most of them.&lt;/p&gt;

&lt;p&gt;I will be releasing the code sometime next week &amp;ndash; on github, most likely. I&amp;rsquo;ll post a link. Meanwhile here&amp;rsquo;s an example that provides a brief glimpse of the API.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#include "dbic++.h"
#include &amp;lt;unistd.h&amp;gt;

using namespace std;
using namespace dbi;

int main() {

    // Handle h ("driver", "user", "password", "database", "host", "port");
    Handle h ("postgresql", getlogin(), "", "dbicpp");

    Statement st (h, "SELECT id, name, email FROM users WHERE id &amp;gt;= ? AND id &amp;lt; ?");

    // bind and execute the statement.
    st % 1L, 10L;
    st.execute();

    ResultRow r;
    while (r = st.fetchRow())
        cout &amp;lt;&amp;lt; r.join("\t") &amp;lt;&amp;lt; endl;

    // or you can do
    st.rewind();
    ResultRowHash rh; 
    while (rh = st.fetchRowHash())
        cout &amp;lt;&amp;lt; rh["id"]    &amp;lt;&amp;lt; "\t"
             &amp;lt;&amp;lt; rh["name"]  &amp;lt;&amp;lt; "\t"
             &amp;lt;&amp;lt; rh["email"] &amp;lt;&amp;lt; endl;

    st.finish();
}
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
</feed>

