Tuesday, January 26, 2010

Founders At Work

For my Birthday I got Jessica Livingston's "Founders At Work: Stories of Startups' Early Days". It was an enjoyable book and over the past two weeks I quickly went through it. The book is broken up into thirty-two different interviews with company founders. Most of the stories are about web companies, but there are a few hardware stories mixed in.

Covering so many different companies and individuals one coundn't help but compare them. You have companies like Apple that started with the brains behind it to make a really fantastic product and on the flip side you have Yahoo which looks like it was pure dumb luck. Yahoo was the biggest surprise for me. Started as a way to keep track of links for a dissertation the founders spent the first eight months manually entering in urls people would send them, sometimes eight hours a day the book says. They were in the right place at the right time and that was it. I found it extremely hard to read very deeply into any advice given from companies like Yahoo or HotOrNot which (another random luck story). But to match there are plenty of stories of companies who put in several years of hard work and it paid off. Luck is always a factor in a startup, sometimes it is tiny and sometimes it is a metric ton dragging you forward whether you know it or not.

The story of TiVo mentioned another company called ReplayTV which is no longer around. ReplayTV was TiVo's big competition when they were first growing. All of the stories in the book are mostly successful in the end (the company might have died, but the founder got to cash out). Discussing ReplayTV made me take note of the fact that there was no stories of failed companies. This is probably due to the fact that there are plenty of good stories without having to discuss failures and it is easier to sell a book about companies people have heard of, but no doubt the companies that failed had plenty of good lessons that they learned the hard way.

One story that resinated with me was the story of FireFox. While I lived through looking back I hadn't realized just how much they had going for them at the time. I.E. development team had been discontinued, Netscape only 5% of the users and a horrible interface and no change in sight. Out comes this little Firefox... Comparing that to Arora. Between new versions of I.E. that Microsoft is pushing, new versions of FireFox, Safari and then Chrome comes out. I am glad that I didn't try to really push Arora and kept it as just a QtWebKit browser that utilizes what Qt has to offer.

The book has a large quantity of material and at times I felt a few stories were just repeating earlier ones, but it was a fun read, I picked up a few things and while it doesn't get into a lot of technical detail there are lessons that you can pickup from the book such as: You will probably need to change your startup idea, it will be stressful, and patience and persistence pays off.

Sunday, January 03, 2010

Hay Maze


A week before Holloween Jen and I walked to Parlee's farm, a local farm just a few miles away where they had setup a seven acre hay maze. Going through a life size maze is one of those things I always wanted to do as a kid so when we discovered one nearby we went over on the next sunny weekend to try it out.



Walking through the maze took us almost an hour to get through. Even though the hay was only about four feet tall (at the highest) I couldn't see very far and wasn't able to follow were the trail went with my eyes because the hay would blend together. There are two bridges in the second half of the maze that you get to walk on top of and look out over the maze. Amusingly though when you got to the bridge and looked out you really couldn't solve the maze just by looking because the after twenty feet or so it is all just meshes together and you can't tell where the paths are.


This was very nice as I feared that I would just stand still look at the maze and then walk the correct path. This meant that I got to enjoy solving the maze with only the paths I have walked (I wasn't even really sure of the dimensions of the farm/hay fields). When you are solving randomly generated mazes on paper as a kid the only real rule was 'always take a right and you can't go wrong'. But with a life size hay maze you get all sorts of social clues that I quickly started to notice.

In a random maze generated by a computer one of the paths from the very first junction could lead you to the exit. When it is maze number 8 of 500 in a book that is ok, but for a hay maze that makes it not very fun. They want you to have fun and this knowledge can be exploited. Fun is spending a while in the maze, getting to go over each bridge and not wasting too much time on the wrong path. This particular maze was subdivided into sub sections. Each section was its own little maze with one correct path out to the next section. This way if you are lucky on one of the smaller mazes you might not be so lucky on the next (thus having more fun) and you can't spent too much time going the wrong way. Of course once you realize this you can exploit it by taking paths that would lead to where you think the next area would be and knowing you are going the right way if you have not reached a dead end in a while.


Another thing I noticed was that the creators of the maze made several sections that were designed for a human. In one junction that you enter you have four paths in front of you, but if you turn around you will find another path just to the right of where you entered the junction. Visually hidden from the entrance this path and separate from the other four it was clearly the correct path because it would be fun to discover it after walking down one of the wrong paths and returning.

Lastly given that there are people in the maze not only can you see them exploring areas ahead of you and behind you, but you can hear their joy and anguish. This quickly provides hints about what to do in the future. From how big a section is to which side has the right/wrong path. At times I couldn't help but laugh at the family who was stuck in the section behind us and the kids found dead end after dead end.

I went to the maze not really sure what I would expect. I thought it would be similar to every randomly created maze I have dealt with, but found something different and much more interesting. While actually getting through the maze was fun everything else about the maze was much more exhilarating. From ponding how one might make (and exploit) a "fun maze", being outside, people watching, and having fun with Jen made it a very memorable experience. If you ever get the opportunity to go through a life size maze I very much recommend it.

Sunday, July 05, 2009

Managing multiple Qt versions with Git clone

Like many Qt developers I have many different versions of Qt on one computer. In the past I used to have a copy of nearly every tarball and a built version. My /home/ben/dev directory looked something like this:
...
qt-all-opensource-src-4.5.0/
qt-all-opensource-src-4.5.0.tar.bz2
qt-all-opensource-src-4.5.1/
qt-all-opensource-src-4.5.1.tar.bz2
qt-all-opensource-src-4.5.2/
qt-all-opensource-src-4.5.2.tar.bz2
...

Now that the Qt repository has been open for a while we can take advantage of a nice feature of git clone called local cloning. On my computer I have a primary Qt repository (/home/ben/dev/qt-master/) which has has remotes pointing to my personal Qt fork and the main Qt repository.

Rather then downloading a tarball of 4.5.2 I now do a local clone of Qt and then checkout the tag "v4.5.2". Although Gitorious does not list tags (missing feature?) both Qt 4.5.1 and 4.5.2 have been tagged in the Qt Git repository.
git clone -l qt-master qt-4.5.2
cd qt-4.5.2
git tag -l # List the available tags I can checkout
git checkout v4.5.2
A local clone will share object files when possible saving you a lot of hard drive space. For Qt versions older then 4.5.1 I still have the tarballs, but going forward there are a lot of advantages to using this beyond saving space. In the past when tracking down a bug in a specific release I have often tweaked the code or applied a patch. Now that the releases are fully backed by Git I can quickly revert back to the release as well as using tools like git blame and git log to get much more information about any files I am investigating. You also get the tests and util directories which are stripped out of releases.

In addition to the releases I also have a clone for the Qt 4.5 branch, what will be 4.5.3. qt-master is the original Git repository which tracks what will become Qt 4.6. After this change I ended up with a directory like this:
...
qt-all-opensource-src-4.5.0/
qt-all-opensource-src-4.5.0.tar.bz2
qt-4.5.1/
qt-4.5.2/
qt-4.5/
qt-master/
...

Like many Qt developers I have written a bash script 'qs' that I have in my shell profile to quickly list and switch between Qt directories.
'qs' - Display current Qt version
'qs ' - List all qt directories
'qs qt-4.5.2' - Swap environment to use Qt 4.5.2
'qcd' - Change to the current Qt's directory

This Git clone trick of course applies to any Git based project, not just Qt, but it is yet another hidden gem of the decision to open the Qt repository.

Wednesday, May 13, 2009

Open Qt repository and hidden gems

On Monday Qt Software launched the public repository for Qt. Already there are more then a dozen patches waiting for review in the merge request list and no doubt there will be many more. To help developers submit patches that are higher quality and more likely to be accepted a number of documents have been published on the Qt wiki. Beyond the wiki in the source repository there are new things that could not previously be found in the snapshots or releases. With so many new things I wanted to highlight a few of the items I found most interesting.

Qt Coding Style Followed not only by Qt, but by other projects such as Arora and applications in KDE. Having a common coding style makes code easier to read and review. In the past few years I have seen many applications adopt this style and I look forward to seeing the usage grow.

Api Design Principles An updated version of the old Qt Quarterly article Designing Qt-Style C++ APIs from the first paragraph: "This document tries to summarize the know-how we've accumulated on designing Qt-style APIs. Many of the guidelines are universal; others are more conventional, and we follow them primarily for consistency with existing APIs."

The Little Manual of API Design by Jasmin Blanchette’s In the wiki page for Api Design Principles you find a link to the this pdf which is now public. This first rate book should be manditory reading by any programmer. While many of the examples are from Qt and in C++ most of its ideas apply beyond Qt and C++. Rather then doing it a disservice and trying to describe it, here is the table of contents which gives a good overview.

1 Introduction 5 
2 Characteristics of Good APIs 7
2.1 Easy to learn and memorize . . . . . . . . . . . . . . . . 8
2.2 Leads to readable code . . . . . . . . . . . . . . . . . . 9
2.3 Hard to misuse . . . . . . . . . . . . . . . . . . . . . . 10
2.4 Easy to extend . . . . . . . . . . . . . . . . . . . . . . 12
2.5 Complete . . . . . . . . . . . . . . . . . . . . . . . . . 13
3 The Design Process 15
3.1 Know the requirements . . . . . . . . . . . . . . . . . . 15
3.2 Write use cases before you write any other code . . . . . 15
3.3 Look for similar APIs in the same library . . . . . . . . 16
3.4 Define the API before you implement it . . . . . . . . . . 17
3.5 Have your peers review your API . . . . . . . . . . . . . 17
3.6 Write several examples against the API. . . . . . . . . . 18
3.7 Prepare for extensions. . . . . . . . . . . . . . . . . . 18
3.8 Don’t publish internal APIs without review. . . . . . . . 18
3.9 When in doubt, leave it out . . . . . . . . . . . . . . . 19
4 Design Guidelines 21
4.1 Choose self-explanatory names and signatures . . . . . . . 21
4.2 Choose unambiguous names for related things . . . . . . . 22
4.3 Beware of false consistency . . . . . . . . . . . . . . . 23
4.4 Avoid abbreviations . . . . . . . . . . . . . . . . . . . 25
4.5 Prefer specific names to general names . . . . . . . . . . 25
4.6 Don’t be a slave of an underlying API’s naming practices . 26
4.7 Choose good defaults . . . . . . . . . . . . . . . . . . . 27
4.8 Avoid making your APIs overly clever . . . . . . . . . . . 28
4.9 Pay attention to edge cases . . . . . . . . . . . . . . . 28
4.10 Be careful when defining virtual APIs . . . . . . . . . . 30
4.11 Strive for property-based APIs . . . . . . . . . . . . . 31
4.12 The best API is no API . . . . . . . . . . . . . . . . . 32

Codeing Conventions and Binary Compatibility Workarounds Two good documents that walk through a number of issues that Qt has to deal with being a library that is used on many platforms and compilers. An interesting read for anyone who uses C++ or Qt.

Autotests and Benchmarks After several years of discussing it, the Qt autotests have finally been published. Everyone in KDE can finally checkout how class Foo is tested and when writing patches for Qt an attempt should always be made to write a matching autotest. See some interesting usage of qtestlib and get plenty of example of how to test gui widgets. For those who are writing their own tests check out my QAutoTestGenerator tool which generates test stub files for you to help get you started. Hopefully having this large set of tests open will encourage more Qt projects to have tests. For those who are using Git and qtestlib I have written a git hook that can be found in the Arora repository that will run the matching autotest for files you change to check for any regressions before commiting.

The full commit log for Qt While in the past the qt-snapshot git repository gave a one day granularity the new repository includes every commit with the commit log. The other day while tracking down the QTemporary bug in 4.5.1 I wrote a little test application and Thiago used git bisect to find in twenty minutes the exact commit that had caused the breakage.
git bisect start HEAD v4.5.0 -- src/corelib/io
git bisect run sh -c 'LD_LIBRARY_PATH= make sub-corelib && (ulimit -n 250; /tmp/qfile-bug/qfile-bug)'
With the full commit log tools like bisect and blame become even more useful for inspecting the Qt source code.

With the Qt sourcecode on gitorious It will be easier for developers that need a bug fixed to help contribute and get it fixed in Qt faster. Those who use Qt and want to understand how something works or why it was developed in a particular way will be able to more easily explore the code base. And maybe KDE can even remove the legacy qt-copy. No doubt many good things will come out of the open Qt repository and I look forward to seeing what the community contributes.

Monday, April 20, 2009

World Smallest Transformers


In 2003 Takara released a Transformers toy line that has been dubbed by the fans World Smallest Transformers or WST for short. They are fully transformable two inch tall versions of a bunch of the classic 80's toys. Due to the size and small parts they were only ever sold in Japan. Not too many were made and they were very hard to come by and to make matters worse they were sold in unmarked boxes so you never knew which toy you received. Also there was a different ratio for each toy in the master box making it difficult to collect them all while in the process getting a ton of the common ones. Googling around I was unable to find the ratio's for each toy, so I have put together a list of the toys with the ratios so the data will always be on the Internet.

Wave 1: (2003)
GTF 01A Convoy A (aka Optimus Prime truck cab) 8/48
GTF 01B Convoy B (aka Optimus Prime trailer) 2/48
GTF 02 Lambor (aka Sideswipe) 12/48
GTF 03 Starscream 6/48
GTF 04 Bumble (aka Bumblebee) 12/48
GTF 05 Soundwave (with Jaguar aka Ravage) 6/48
GTF X-1 Skywarp 1/48
GTF X-2 Bumble Red Version (aka Cliffjumper) 1/48

Wave 2: (2004)
GTF 06 Convoy Anime Version (aka Optimus Prime truck cab with blue windows) 12/48
GTF 07 Megatron 8/48
GTF 08 Meister (aka Jazz) 2/48
GTF 09 Prowl 6/48
GTF 10 Alert (aka Red Alert) 6/48
GTF 11 Thrust 12/48
GTF X-3 Streak (aka Silverstreak) 1/48
GTF X-4 Convoy White Version (aka Ultra Magnus cab) 1/48

Dengeki Hobby exclusive Smallest VSX Giftset:
VSX Convoy (variation of Anime colors)
VSX Megatron (aka Megaplex)

Wave 2.5: (2004)
CSV Starscream (from Series 1) 12/48
CSV Soundwave (from Series 1) 8/48
CSV Megatron (from Series 2) 12/48
CSV Convoy Anime Version (from Series 2) 6/48
CSV Meister (from Series 2) 6/48
CSV Hot Rodimus (aka Hot Rod) 2/48
CSV Convoy Container (aka Optimus Prime Anime Trailer) 1/48
CSV Thundercracker 1/48

Wednesday, March 18, 2009

PlanetQt.org launch

After more then a year of thinking about doing it I finally setup planetqt.org and after getting the initial kinks out am officially launching it. While KDE is a major user of Qt there are many applications and developers out there who are not part of the KDE project or who's blogs/news really don't really fit on planetkde.org (or the freedesktop planet). Because of this there are a lot of really interesting Qt projects/tools/stuff out there that people don't know about. So that is why I started Planet Qt. Being made up of people I thought the frame from the Qt4 dance seemed to be a nice logo.

Submit atom/rss feeds for blogs about Qt development or the news feeds of applications/libraries that use Qt and I will add them.

Enjoy!

Monday, March 02, 2009

Tiling An Image With FractalFill

Last summer Adam and I looked into how to speed up tiling an image. In particular we were using QImage (Not a QPixmap so X11 isn't involved in this) and tiling an image on it. This is a pretty common operation, especially on the web where many web pages have repeating backgrounds on items. We came up with a few different ways to do this in Qt.*
  • Naive
    loop over the height 
    loop over the width
    fillRect(tile)

  • QPainter::eraseRect
    Set a background brush to be the tiling image.
    call painter.eraseRect(QRect(0, 0, image.width(), image.height());

  • QPainter::fillRect
    call painter.fillRect(QRect(0, 0, image.width(), image.height(), brush(tile));

  • FractalFill
    painter.drawImage(0, 0, tile)
    while we haven't reached the width and height
    copy everything we have done so far to the next location

Benchmarking this we discovered that eraseRect was pretty horrible, but much more surprising was that our FractalFill algorithm that we tossed together was faster then all of Qt's method. (If any graphics ninja's want to suggest a even better algorithm we are all ears) Adam blogged about this some of the Trolls responded saying that Qt's painting had improved in a private branch which would be part of Qt 4.5. Now that Qt 4.5 is almost out I thought I would revisit to see how the painting performance numbers shaped up to be.

Along with the four algorithms there are two more that are added to the benchmark (Colored yellow in the graphs).

  1. A base line, something that we shouldn't be able to be faster then: just calling painter.fillRect(QRect(0, 0, width, height), color);

  2. Using the FractalFill to paint the whole image with a color.

First up is RGB16 with: 1000x5000





Qt 4.5 really has improved upon Qt 4.4. The problems in eraseRect are gone and everything is faster across the board moving to 4.5 and even better when using the raster engine. But more surprising is that FractalFill is still faster then the two QPainter functions.

Same format (RGB16), but in a larger size: 5000x5000





Again it is clear that eraseRect has been fixed and overall painting has been improved slightly.

Moving on to ARGB32: 1000x5000




And in 5000x5000





On this last one with the larger image sizes I started getting larger differences in the tests results. On ARGB32 the performance seemed to be about the same or slightly better.

Overall performance is much better in Qt 4.5 then 4.4. A big congrats to the Trolls for all their hard work. Painting speed has improved across the board decreasing the runtime of all of the functions. FractalFill is still faster then using QPainter's fillRect or eraseRect so for the time being if you looking for something faster then Qt's fill functions for tiling this might be useful for you.

Notes:
I have uploaded the source for the test application to a GitHub repository. I ran the application multiple times on my computer to generate the numbers using the release version of Qt, building from qt-snapshot with 4.3.2 on ubuntu and qt3compat turned off. Now that Qt 4.5 is out it would probably be worth converting to the new benchmark tool. I used Google's graph service to generate the graphs.

* Analyzing each algorithm to determining their Big-O notation is left as an exercise to the reader. ;)