Planet Qt - Highlighting Qt development and applications

Planet Qt needs your help. Submit rss/atom feeds to your favorite blogs about Qt development or news about Qt Applications. For developers that only occasionally blog about Qt use the rss feed for articles tagged with Qt.

May 17, 2012

Zchydem's Blog

Qt5: New signal and slot syntax

I thought, that I should write about this topic, because it’s time to start my self-education project again and see how I can take new features of Qt in use. I’m not sure how useful this blog post is because there already is a nice wiki page available about the same topic on qt-project.org. But for those, who [...]

by zchydem at May 17, 2012 09:41 PM

Michael Hasselmann

Get ready for Qt Contributor Summit!

With only roughly over five weeks to go, QtCS 2012 is approaching fast on the event horizon (pun absolutely intended). During the TiZen Developer Conference, Quim Gil and I, with help from Robin Burchell, found time to work on a draft, the result being visible in the QtDev wiki. Don’t be scared by the amount of pre-scheduled sessions, we will try to keep it as unconference-y as possible. However this allows us to properly prepare selected sessions.

Please keep in mind that QtCS 2012 is invite-only.

Session presenters, prepare!

If you are a maintainer of a Qt Essentials module, then you will have to drive one of the pre-scheduled sessions.

It might be a good idea to start writing a report about what happened in your area over the last couple of months, and where you plan to take your module for the Qt 5.1 release. Attendees of your session will probably expect you to talk about Qt 5 migration and how it will affect code using your module. On top of that, the most urgent bugs might get discussed, along with new feature requests, so please be prepared.

If you find a topic that isn’t showing up in the program yet, consider to get in touch with other interested folks (the Qt development mailing list or #qt IRC channel are good places to ask). With sufficient feedback, you should have everything it needs to drive the session yourself!

Plenary sessions

The first day will start with the State of the Union session about Qt 5 and Qt 5.1, summarizing where we are and where do we want to go with the Qt project.

The second day is about betting on Qt Quick, covering topics such as theming, platform integration and cross-platform. We want to invite the maintainers and a few vendors/users/contributors to expose their thoughts and needs with the hope of bringing a common understanding.

For the last day, we have a special surprise, as the topic will be HTML5 & the web. I am aware that this will raise a lot of controversy among the community, but it is an area where we need to find answers. With all the latest interest in web technologies, the answer can no longer be “We don’t do web”. That’s what killed the dinosaurs, remember? Then again, Qt already has better answers then that, so it’s about time for a fierce but honest panel discussion, including the Qt WebKit maintainers and other users/contributors driving this area.

Hack'n'Tell

Of course we also want to you to feel entertained during the summit, which is why we want to try out Hack'n'Tell sessions.

The rules are simple: Show us a cool hack involving Qt. You got 5 minutes. No slides.

I realize that preparing cool hacks takes some time, which is the original intent for this blog post: to announce the Call for Cute Hacks. For the first day at least, it would be great to have a couple of presenters before the summit starts. For the other days, I kind of hope that the summit itself will spark great ideas and demos that need to be shown immediately.

I hope I got you excited a bit, so let’s make QtCS 2012 an event to remember!

Permalink | Leave a comment  »

May 17, 2012 09:02 AM

May 16, 2012

Commercial Qt

Qt Commercial Support Weekly #20: Visualizing the Logical

In QHeaderView there is admittedly a confusing concept of referring to the different header sections, they can be referred to by their logical index or by their visual index. And then when you start trying to use the functions to go from one to th...

May 16, 2012 04:07 PM

May 15, 2012

Mirko Boehm

QMake, Unit Tests and dynamic libraries under test

A repeated problem we run into when using QMake is that it focuses on being a build tool, and because of that does not implement some features for executing parts of the project (like tests). Others ran into this issue as well, as for example this discussion of specifying run configurations from QMake on Qt DevNet indicates. Multi-part projects often consist of dynamic libraries that contain the features, and applications and tests that link this library. Amongst other things, this approach allows tests to link objects which contain the application’s code. Now when the tests are executed, the dynamic linker needs to be able to pick up the freshly built library and link the test with it at execution time. Projects usually run test cases with make test, and ideally the tests should execute out of the box after the sources have been configured and built (out of the box meaning that no tweaking of the environment variables should be needed between make and make test). After all, it should be as easy as possible for developers to execute tests.

This is also a problem in IDEs like Qt Creator, but also others – for every build configuration (having separate shadow build directories), the developer needs to configure the library path before being able to debug the application. This second problem needs to be fixed in the IDEs. For the first one – configuring test runs from the QMake .pro file – we have developed a solution called QMakeTestRunner that takes care of the problem. QMakeTestRunner assists in setting library paths when running unit tests in products built with QMake. It makes make test work out of the box right after makefiles have been generated. It is Free Software, published on Github, and small and easy to integrate into projects as a Git submodule. Much of this information will go into the documentation on Github as well.

Motivation, aka “The Problem”

QMake as a build system is simple and complete for building code, but it lacks a simple way to run unit tests dependent on libraries which are part of the project itself. In this case, paths which are created in the build directory need to be added to the dynamic linker library path before the tests can be executed. Especially with shadow builds, this would require manual setup, and make test would not work out of the box after QMake has been run.

QMakeTestRunner, aka “The Solution”

As soon as any target in a QMake project has the testcase attribute assigned to CONFIG, QMake automatically generates a target called check that runs this test. Unfortunately, make check does not allow the manipulation of the linker paths before running the tests either. QMakeTestRunner contains boilerplate code that wraps QMake’s make check target with a new one called make test, and through variables specified in the QMake file allows the specification of paths to be added to the linker path.

Usage

QMakeTestRunner is intended to be used as a git submodule to the main project. It should not require any modifications to be used. It requires Python to be in the path, checks for it, and the QMake run will fail if Python cannot be detected. When using other version control systems than Git, QMakeTestRunner should be small enough to simply be copied into the project as a subdirectory.

Project configuration example

The following example adds the directory libs/ in the project build directory to the linker path. It assumes the QMakeTestRunner repo is located under 3rdparty/QMakeTestRunner. The path where the dynamic library is generated in below the output (build) directory, which is why it is prefixed with OUT_PWD:

TEST_LIB_PATHS += $$OUT_PWD/libs
include( 3rdparty/QMakeTestRunner/testtarget.pri )

To trigger extra diagnostic output of the test runner, add

TEST_VERBOSE = 1

before including testtarget.pri.

make test

Once testtarget.pri has been included, a test target is defined in the makefiles. Simply run make test to execute the original make check with the necessary paths.

Mac OSX Frameworks

Frameworks on OSX are a different kind of library. The framework path is passed into the dynamic linker using a different environment variable. To specify a framework path, set the TEST_FRAMEWORK_PATHS variable before including testtarget.pri.

TEST_FRAMEWORK_PATHS += $$OUT_PWD/frameworks

Setting up QMakeTestRunner as a Git submodule

Using a Git submodule has the benefit that the code for the runner does not need to be duplicated into the repository of the project that is supposed to use it. It also makes it easy to pull updates to the test runner by simply updating the submodule to a new revision. To add the submodule as 3rdparty/QMakeTestRunner in your project, follow these steps:

> mkdir -p 3rdparty
> git submodule add git://github.com/AgileWorkersSoftware/QMakeTestRunner.git 3rdparty/QMakeTestRunner
> git submodule init

The directory 3rdparty/QMakeTestRunner should now contain the current revision of the test runner scripts.

License, contributions, issues and support

QMakeTestRunner is Free Software licensed under the GPL, version 3. Contributions to it are welcome, please propose them as Github pull requests. To submit a bug report or feature wish, please use the Github issue tracker for the project.

Commercial support for QMaketestRunner or general issues with QMake is provided by Agile Workers Software. We are happy to help.

by Mirko Boehm at May 15, 2012 07:18 PM

May 09, 2012

Tomahawk

Interview: Muesli Talks Tomahawk


Music Ally recently interviewed or very own Muesli (aka Christian Muehlhaeuser) about music, technology and Tomahawk. We've reposted the Q&A here here so you can get a little more insight into our fearless leader, his background and where we are going.
 
1. Can you tell me about one of your favourite webs projects you’ve worked on and why? 
While I technically never really worked on Last.fm's website - I was busy working on their desktop apps - I probably still have to go with that project. I had joined the company fairly early, before the entire Web 2.0 craze kicked in, and it was astonishing to see how our fairly small team handled everything as it grew. Back then we were only five or six people - and almost four years later, when I left, we had over 20 million users and more than 120 people were sitting in the office. In that short time, we had pretty much experienced every startup scenario you could imagine: from camping and living in the office, learning how to scale and deal with our growing userbase, dealing with the fear of surviving as a startup, taking on investors, introducing major design changes that caused user uproar, to eventually selling the company. It was always a bit of a rollercoaster ride and I probably learned more in those 4 years than in all my other projects combined. 

2. What have been the main challenges with developing the Tomahawk player? 
Tomahawk is a bit of a swiss army knife. It's fairly easy to build a client / server system where you control both ends, but we don't with Tomahawk. It's a music player that aims to bring all the various scattered music silos and experiences (across the globe) together under one roof... and then enhance the user experience (social, dynamic programming, discovery, etc.) across the top of it all. You can build playlists and add tracks not only from your local collection, but also from Spotify, YouTube, SoundCloud, Official.fm, Jamendo, your remote and online music collections, and many more. The hardest challenge is to support this variety of different APIs and bringing them together in one coherent, consistent user interface. You shouldn't have to jump from one music service's interface to another's just because you want to listen to a different song - just like tuning in to another radio station or TV channel doesn't require you to turn on a different device either. We see the need for that one place where you can listen to anything from Lady Gaga to your cousin's punk band - in one seamless interface. 

3. What do you think will be the trends in the next breed of music services?
As the debate continues to grow about online streaming royalty payouts, I unfortunately think we will see a reverse trend of more content fragmentation as bigger artists pull out of some services and potentially sign more lucrative exclusives with others. Similarly, I think there will be more niche services that aim not to license the entirety of recorded music, but just small subsets of genres and artists. We believe that both of these trends will further necessitate solutions like Tomahawk to fill those holes in one service's catalog from other available sources. The only one that has the real ability to access all of the content a specific users wants is that user. This is fundamental to our approach that a user brings all the content they care about, from everywhere they have access to it, into a player that can just do the right things with it. 
 
4. What can be done to make innovation in music easier for developers? I really believe that music already is one of the most innovative spaces on the web right now. Many projects and companies exist and support open standards. The Echo Nest, Musicbrainz and Last.fm let you access not only your own data, but you're pretty much free to play with all their data, too. Compared to books, movies and even TV - we're light years ahead. On the other hand, licensing content is probably still the biggest issue for new music platforms. As a startup with a small userbase and limited financial backing it's pretty much impossible to reach a licensing agreement with one of the majors, let alone all of them. I wonder how many brilliant ideas will never see the light of day because of developers getting frustrated by the process. Tomahawk tries to tackle this problem by letting developers play with the (free) meta-data and then bringing the content to the table from other services that their users already have access to. Your project shouldn't have to stream a song to me (and then pay for it) if I've already bought the track on iTunes - just play it from my disk. Not only is Tomahawk open-source, but it also has APIs that already let other projects and hacks leverage its content resolution. For example, the core team recently built Toma.hk (a website for sharing music across services and territories) using these APIs. Others have built things that let you scrape playlist metadata from loads of websites and then play them back using Tomahawk (and the content user has available) and someone just started to catalog all of John Peel's record collection as Tomahawk links. All this depends on open standards and data portability though, so I can't emphasize enough how important they really are. We believe that a user should own all their data (e.g. playlists) and be able to easily take them or share them across services. We hope this is a value that will be be adopted by all of the other players in the ecosystem as well. 

5. Tell us about a digital tool, platform, website or service you really admire from a technical perspective and why? 
There's a lot to admire out there: people built platforms that can deal with more than 25.000 tweets, 8.000 status updates and 800 scrobbles - PER SECOND - and we expect them to run day and night without a hiccup. Anyone who has worked on such a service or website knows how to admire something that most people take for granted nowadays. It's a lot of blood, sweat and tears.

Extra Credit: What's the story behind the name "Tomahawk"?
A tomahawk is a universal tool - one that can be used as a hammer, a knife, an axe. It was often the one and only tool you'd carry around. Given the great utility of such a tool, we felt the name seemed to embody what we strive to provide.

by jherskowitz at May 09, 2012 04:26 PM

Qt Labs

Qt Creator 2.5.0 released

The Qt Creator 2.5.0 final has been released! There are lots of new features and improvements in this release, I’ll highlight a few here, some others are probably already mentioned in our beta blog post, and you’ll find a more complete list in our changes file.

So, new features and improvements include but are not limited to:

  • You can repeat a recent search with the same parameters with a simple click on “Search Again”
  • “Execute” Locator filter lets you run arbitrary commands in a shell from Qt Creator (“! <some command>”) (thanks to Yuchen Deng!)
  • Experimental plugin that shows “TODO” items from your sources (thanks to Dmitry Savchenko and Vasiliy Sorokin!)
  • Experimental plugin for autotools based projects (thanks to Patricia Santana Cruz and Openismus GmbH!)
  • Mac OS X Lion users will we happy to know that QTCREATORBUG-6222 which prevented adding some Qt Versions has finally been fixed
  • A very basic version of a C++ refactoring action that adds an #include for an unknown identifier has been added (move cursor on identifier, press Alt+Return (Option+Return on Mac OS X))
  • A very basic version of a C++ “extract method” refactoring action
  • Improved support of C++11 (nullptr, constexpr, static_assert, noexcept, inline namespaces, auto, lambdas)
  • Rearrange C++ method arguments (thanks to Bojan Petrovic!)
  • New hints and warnings for QML code, including an option to prevent them for specific lines (with a special comment)

Note for Windows MinGW Users

We decided to remove the custom MinGW distribution and MinGW gdb from our Qt Creator-only Windows binary distribution package. The original reasons to include it there (it was the predecessor of the Qt SDK) are since a while now filled by the Qt SDK. Also, updating the shipped version is a legal hassle as long as the binaries are provided through Nokia, but we also don’t want to ship stone age versions. We are working on build infrastructure for the Qt Project itself though, that we ultimately want to use to build Qt Creator packages, snapshots, and more. Currently, on http://builds.qt-project.org, you find Qt Creator snapshots for Linux and Windows, and also a Python enabled MinGW gdb (that reportedly doesn’t work on Windows XP). It’s still possible to install MinGW and gdb separately and register them in Qt Creator. We are not removing the support for it from Qt Creator.

Previously shipped MinGW: ftp://ftp.qt.nokia.com/misc/MinGW-gcc440_1.zip
Previously shipped MinGW gdb: ftp://ftp.qt.nokia.com/misc/gdb/7.2/qtcreator-gdb-7.2-mingw-x86.zip

Up to date MinGW: http://www.mingw.org (we might provide a compact version like the one in the old installer later)
Python enabled MinGW gdb 7.4: http://builds.qt-project.org/job/gdb-windows/ (compiled on Windows 7, doesn’t work on Windows XP)

Thanks to All Contributors

Too many to include them all here, please scroll to the end of our changes file!

Download

See our Release Page

by Eike Ziller at May 09, 2012 02:02 PM

May 08, 2012

Commercial Qt

Qt Commercial Support Weekly #19: How to Write Your Own Static Library with Qt

Qt Commercial customers have a great advantage to safely compile Qt statically and create their own static libraries and applications. Here, I have gathered some practicalities related to working with statically-linked Qt. Hopefully, this provides...

May 08, 2012 07:10 PM

May 06, 2012

Swift

Swift Hackathon Roundup

Last sunday, we finished our week-long Swift Hackathon, and it was a great success, leading to Swift 2.0-beta1! Here’s a list of the things we achieved during that week.

First of all, the goal of the week was to find and fix as many bugs as possible. This is what our ‘hackathon bug count dials’ were displaying at the end of the week:

Hackathon Week Bug Counter

In only one week, we found 19 bugs, and fixed 64! Not a bad result for our first hackathon, don’t you think? As you can see from the trend, we put a big dent in the list of open bugs:

Hackathon Week Bug Trend

And if fixing all these bugs wasn’t enough, we found the time to do some other things on the side as well during the week:

  • Together with Olly Betts, we finished our Debian packages, and submitted them to Debian. So, expect both Swift and Swiften to be available from the official Debian repositories soon!
  • We set up a build for the brand new Ubuntu 12.04 (Precise Pangolin)
  • We started fixing and cleaning up translation strings

Thanks again to all the people who have helped us during this excellent week!

by Remko Tronçon at May 06, 2012 12:00 AM

May 04, 2012

Swift

Swift 2.0-beta1 Released

After another year of development, we’re happy to announce that we released our first Swift 2.0 beta! We encourage everyone who is interested in helping us with testing to try out this new release, as it has many bugfixes and enhancements (see the release notes for more details).

Thanks to the hackathon week (of which details will be posted shortly), we believe this first beta to be pretty stable. Nevertheless, should you find some bugs, please come and tell us about it!

by Remko Tronçon at May 04, 2012 12:00 AM

May 03, 2012

ICS

Qt and HTML5: The Best of Both Worlds (25:09)

Qt and HTML5: The Best of Both Worlds (25:09) This webcast describes HTML5 and how it can be used to develop applications, both on its own and with the Qt toolkit.
Flash View Online H.264 Download Ipod Download

May 03, 2012 05:02 PM

April 28, 2012

Monkey Studio IDE

Monkey Studio IDE 1.9.0.2 Released

Dear MkS users.
MkS team is proud to announce the availability of the Monkey Studio IDE 1.9.0.2.
This is a bug fixe release for the 1.9.0.0 version.
A list of the new improvements and some screenshots can be found here.
You can grab your copy of the new version from here.
Or, from your package manager if you are on Gnu/Linux/Unix like.

We hope you benefit from the new version.
MkS Team.

by pasnox at April 28, 2012 12:16 PM

April 26, 2012

Swift

Swift Hackathon Update

We’re just halfway through our Swift Hackathon, so we thought we'ld update you about the progress we’ve made so far. In fact, a screenshot of our live hackathon week bug counter sums this up quite well:

Hackathon Week Bug Counter

That’s right: in merely a couple of days, we managed to fix 50 (more than half!) of the open bugs, and found 17 new bugs. And what’s more: we still have the whole weekend ahead of us, so you still have a chance to join us in fixing, testing, and improving Swift!

A big thank you to all the people who have been helping us out so far!

by Remko Tronçon at April 26, 2012 12:00 AM

April 25, 2012

The Qt Blog

Planning Qt Contributors Summit

Qt Contributors Summit 2011, by Alexandra Leisse.

Hackers' Lounge at Qt Contributors Summit 2011, by Alexandra Leisse.

The second edition of the Qt Contributors Summit is warming up. Venue and dates are secured: June 21-23 in Berlin. Some sponsors have already stepped in and more will come. The schedule is being discussed as we speak but in any case it’s all about technical sessions based on status sharing, planning and discussion. It’s the first big event organized in full Qt Project mode! We are working hard to offer the best context for up to 225 contributors taking Qt 5 to the next level.

Registration is open with more than 50 participants confirmed. Maintainers, approvers, contributors of code and other species are welcome. All maintainers are expected to be there or nominate a substitute for their module. If you meet the participation criteria you are welcome to apply as soon as possible. Note that this is an invitation-only event: please wait our confirmation before booking your trip.

We aim to have a modest budget for sponsoring travel expenses in special cases.  If you are in this situation you must apply for an invitation right now, so we can budget properly.

The budget of the event is entirely covered with the funds from kind sponsors. Nokia, Research In Motion, Digia, ICS, Intel, Froglogic, e-GITS and KDAB have already stepped in, and we are in conversations with more. Nokia and RIM are sharing the XL sponsorship package, a new precedent reflecting the new possibilities of the Qt Project. The deadline for accepting new sponsors is May 18. After that we will start producing the printed materials. In addition to the sponsorship benefits, all sponsors get real-time access to the accounts of the event and voice for suggestions on how to do better.

We are planning to combine some plenary sessions defined in advance with a grid of parallel sessions, most of them scheduled ad-hoc in pure unconference style. The plan is to focus on technical planning and collaboration between the developers of Qt, giving a secondary role (or no role) to unilateral presentations, marketing & outreach. There is still a lot of work to do! If you want to get involved meet us in the Qt Project [Marketing] list.

by Quim Gil at April 25, 2012 05:09 PM

Bo Thorsen

Encapsulation in QML Components

In QML, it’s so easy to use properties of components directly, and it’s even the way most examples do it. But here’s my quesion: If we consider this the wrong approach in C++, isn’t it wrong in QML as well? The answer is usually yes.

Here, I’ll show you how I think the best practice of building QML components is. It seems so simple, maybe even trivial. But I have met a lot of code that doesn’t follow it, and seen the problems that follow. QML is still so new, that best practice isn’t common knowledge. And in many cases, best practice haven’t even been discovered yet.

Let me give a quick example that shows the problem: You have created a Button component with all the bells and whistles such a component needs. You chose to build it using a Rectangle, so the border is handled by an existing component. Reuse is always a good and popular choice.

Here is some of the code of how the Button could be done:

Button.qml:
Rectangle {
    id: button
    border.width: 1
    signal clicked()
    property alias text: buttonText.text
    Text {
        id: buttonText
        anchors.centerIn: parent
    }
    ...
}

You now declare a Button, set the size and the text, and that’s it. However, you might also want to have a different border, so this is what we do in the UI QML file:

Ui.qml:
Rectangle {
    width: 360
    height: 360
    Button {
        anchors.centerIn: parent
        text: "Hello World"
        width: 100
        height: 30
        border.width: 2
        border.color: "blue"
    }
    ...

Now, here’s the problem: If you decide to expand the Button with other choices of how it can look, you will have a problem. For example, you might want to offer a BorderImage for the way the Button looks. But with the current use of a Rectangle, you can’t do this without modifying the code that uses this Button.

This is exactly the problem encapsulation solves: It allows you to make local changes to your component without modifying all the code that uses it.

The simple solution of the Button is to make it an Item that has a Rectangle. In OO terms, this changes from inheritance to aggregation.

My solution for creating QML components is to nearly always base them on Item, and expose whatever properties I want. The interface to my components is the sum of properties, functions and signals. How I choose to implement the component itself is an implementation detail, and should not be available to other components.

For a simple example, suppose we have a system where a bunch of Text items should always follow a shared style. If the style changes, all text must follow. In fact, the only thing the users of the text item can set, is the text itself.

This could clearly be done with Text directly:

StyledText.qml:
Text {
    // Event handlers to set the Style parts here:
    ...
}

This a valid choice, we simply need to tell ourselves that we shouldn’t set the color, size etc. directly, but allow the central style code to set it. And this is of course doomed. Some day, we hire a new coder, or forget ourselves. Whatever the reason, we will break the rules.

The proper solution is to encapsulate the component and hide the implementation behind the Item:

StyledText.qml:
Item {
    property alias text: textItem.text
    Text {
        anchors.fill: parent
        // Event handlers to set the Style parts here:
        ...
    }
}

It seems so simple, but I have seen a bunch of QML code that doesn’t do this. Every time you start modifying the code of components, you wonder what you break. And this only becomes much more valuable with real components that have much more complexity than the simple example code I have here.

If you follow this pattern instead, you will create robust and encapsulated components with no properties accessible by accident.

by Bo Thorsen at April 25, 2012 11:53 AM

Mathias Hasselmann

Using Full Text Search Engines as Datastore

It's a common design to use full text search engines only for free text searches, but to store the actual structured data in a separate database. Such designs come at a cost. Therefore Openismus asked me to build upon my previous post, where I analyzed several FTS engines. This time I'll research if we could use the full text search index itself as our primary data store.

Relations

A first obvious limitation is the lack of joins. So to use the FTS index as data store, you must denormalize your data. That is, instead of storing your movie database in distinct entity tables like Movie and Artist, linked by relationship tables like isLeadActor or isDirector, you must find a way to put everything into one single flat table. This isn't entirely nice in terms of redundancy and consistency. On the other hand joining tables is what makes relational databases slow and hinders distributing them across servers. Is there someone whispering "NoSQL"? Well. Yes, while I absolutely dislike their striking marketing: They are on to something, and with our journey today we enter their land.

Seems I've lost myself in chatting, so back on topic. So to store data in a FTS index we must denormalize our data. Luckily they make it easier than it sounds. In opposition to the relational model, there is no need to create complex relationships, just to assign more than only one actor or director to a movie: When adding artists to your movie you just tag each name with the proper field prefix before adding it to the index, and you are done. FTS engines natively support multi-value fields!

With some additional effort it also should be possible to store more structured data in those multi-value fields, things like (release-date, country), or (actor, role): You'd add more prefixes and use the positional information stored for phrase searches to reliably identify those fields. Sadly my time is too limited to research this more in detail, but the Internet surely has documents about this. Well, or for additional fun you can try to figure it out yourself.

Exact Matches

Now a match reported by an FTS engine only tells us that the document or the chosen field contains the phrase we were looking for. When searching for `title:"The Matrix"` any FTS engine will not only return the first movie of the Wachowskis' triology, it also will give matches for the other two movies, and works like *"Making 'The Matrix'"*. So for doing exact lookups we'll have to filter the initial result, and drop any document that doesn't exactly match our requirements. Sadly we really must check the field value instead of just checking the computed score: For instance with Lucene both *"The Matrix"* and *"Making 'The Matrix'"* will get a score of 100%, since both documents fully satisfy all terms of the query. Also we cannot use the score as indicator to only check fields for documents that got at least 100%: When searching for `director:"Quentin Tarantino"` the movie *"Inglourious Basterds"* will get less than 100%, since Tarantino was working with Eli Roth for this movie. So this additional filtering sounds expensive at the first moment, but remember that our index lookup dramatically reduced the data set already. When looking for `title:"The Matrix"` in the *imdb-50* data set, we talk about checking 9 documents instead of 121,587 documents for example. For useful data sets we won't notice the overhead, like the test results below are showing.

You can just add unanalyzed fields and use term queries on them like kamstrup pointed out.

Data Types

So we've learned that lack of relations isn't much of a problem for many useful datasets, but structured data is not only about relationships, it also is about data types. Full Text Search engines only support lexicographical order, so they surely fail for dates and numbers. You surely cannot use them to find documents within a given range!

I am sorry to disappoint you. The people researching FTS are smarter than that. Actually properly sorting and ranging dates, while only using lexicographic order is trivial. Most probably you have done it yourself already. Simply store your dates in ISO format, that is YYYY-MM-DDThh:mm:ss.SSSNNN or any prefix of this, and you are done. Omit the separators if you prefer. ISO-8601 explicitly is designed for lexicographic sorting.

So how do you do this with numbers? You could prefix them, for instance with zeros, to get a fixed width. This works reasonably if you know your number ranges, and in most cases you do. Sometimes you know the range from your application's context, e.g. the first known celluloid film was recorded in 1888. More easily you just use your technical limits, like [-263..263-1] for long integers. While first experiments really followed that approach, padding numbers with up to 18 zeros isn't exactly efficient or pretty. Also we didn't talk about floating point numbers yet. Therefore FTS engines like Lucene or Xapian provide more efficient mechanisms for turning numbers into sortable strings. First they write a prefix indicating number precision (64 bit, 32 bit, 10 bit, ...). Then they convert the numbers to some unsigned format, and apply some kind of base-128 encoding to the resulting bytes. The most significant bit gets stored first. For floating point numbers they shuffle some bits of the number's IEEE-754 representation. The resulting, sortable 64 bit integer then is encoded like any other number. You can consult Lucene's documentation, and the source code of Lucene::NumericUtils, or Xapian::sortable_serialise for details.

Benchmarks

Hope I didn't lose you with all this theory, now it is benchmark time!

To test how useful FTS engines are for storing arbitrary data I've extended my previous benchmark to better support range searches, and to support exact matching of fields. I've also added Michal Hruby's patch for supporting prefix searches. Since the prefix search gives countless hits, the query results consistently are limited to 10.000 rows now. I've dropped QtCLucene for now since it doesn't seem to support numeric range searches and such. It was forked from Java Lucene a long time ago. For SQLite I ran two sets of tests: bm_sqlite doesn't create indices for fields like movie title or artist names. Since such setup is unfair when comparing with FTS engines, the second set bm_sqlite_index creates indices for all fields we perform lookups for. For tracker we again test the Nepomok media ontology (bm_tracker) and a optimized ontology (bm_tracker_flat), that attaches all properties to the same RDF class. I had to disable prefix searches for bm_tracker: The query ran for more than 2 hours on the dataset with 17k movies. I seriously wish I'd get sponsored to improve Tracker's data model!

Source code still is in the fts-benchmark repository, tagged as release/0.3.

Results and Discussion

Each query got run 7 times on 5 different data sets. This time I didn't take the mean of the query execution times. The individual results of each dataset are grouped together and labeled with qxx_t1 to qxx_t7. Data and result sets grow with each group.

Also be careful when reading the charts as time is scaled logarithmically. You might want to consult the raw data tables below for details. Please keep in mind that the basic goal of this benchmarks is to test scalability, not raw performance. Therefore I don't mind much if an engine is 10 times slower than another for small data sets. Constant performance is the ideal result.

You'll also notice that some charts have gaps for bm_tracker. Like explained above I had to skip bm_tracker for few data sets, as tracker took way to long to perform those benchmarks.

rating:[90 TO 99]

Lucene++ appears significantly slower than its competition for small data sets, but then gives comparable results for data sets with more than 3,000 movies. Still I would not overrate this finding: We are talking about lookup times in the range of 10 ms. That's still pretty fast and close to measurement limits like the spikes in the other engine's results show.

release:[1999/01/01 TO 1999/09/30]

This results are similar to the rating:[90 TO 99] query.

release=1999/03/31

For this query you see the importance of having an index for your lookup keys: Performance of bm_lucene++ and bm_sqlite_index remains almost constant, while effort of the other engines grows dramatically as the data size grows.

Xapian's bad performance comes as a surprise, but actually I am to blame here: For stupid reasons I've implemented this very search as range search in Lucene++ and Xapian (release:[1999/03/31 TO 1999/03/31]). As the results indicate Lucene++ seems to putting more effort into optimizing range searches, and compensates my mistake.

title=The Matrix

Similar results as for release=1999/03/31, only that Xapian behaves as expected now. When given a proper query it also shows constant lookup time for exact phrase searches.

director=Quentin Tarantino

With this query you see the advantage you get from using denormalized tables: Lucene++ and Xapian just are as efficient as in the previous tests, but as a not so big surprise Tracker with the flat ontology now beats all remaining engines, including bm_sqlite_index.

T*

Performance of the different engines is similar to each other when performing prefix searches.

Raw Result Data

rating:[90 TO 99] - 9 movies, 3 matches
t1t2t3t4t5t6t7
bm_lucene++12.333 ms10.409 ms9.885 ms9.821 ms10.221 ms9.840 ms9.986 ms
bm_sqlite0.196 ms0.169 ms0.169 ms0.173 ms0.166 ms0.167 ms0.167 ms
bm_sqlite_index0.207 ms0.183 ms0.172 ms0.192 ms0.193 ms0.173 ms0.172 ms
bm_tracker0.992 ms0.655 ms0.582 ms0.589 ms0.554 ms0.549 ms0.525 ms
bm_tracker_flat0.693 ms0.463 ms0.437 ms0.461 ms0.450 ms0.443 ms0.436 ms
bm_xapian0.242 ms0.201 ms0.200 ms0.198 ms0.200 ms0.199 ms0.197 ms
rating:[90 TO 99] - 1,099 movies, 17 matches
t1t2t3t4t5t6t7
bm_lucene++12.949 ms13.057 ms12.981 ms13.018 ms13.150 ms12.840 ms12.644 ms
bm_sqlite0.696 ms0.546 ms0.516 ms0.530 ms0.515 ms0.518 ms0.522 ms
bm_sqlite_index0.448 ms0.234 ms0.231 ms0.237 ms0.236 ms0.231 ms0.231 ms
bm_tracker5.051 ms4.485 ms4.441 ms4.486 ms4.425 ms4.831 ms4.828 ms
bm_tracker_flat1.465 ms1.133 ms1.110 ms1.104 ms1.108 ms1.108 ms1.108 ms
bm_xapian1.445 ms1.285 ms1.159 ms7.824 ms1.878 ms1.669 ms1.393 ms
rating:[90 TO 99] - 3,216 movies, 35 matches
t1t2t3t4t5t6t7
bm_lucene++14.287 ms13.596 ms13.453 ms13.912 ms13.875 ms14.559 ms13.981 ms
bm_sqlite3.524 ms4.110 ms4.129 ms1.916 ms1.732 ms2.300 ms9.584 ms
bm_sqlite_index0.423 ms2.036 ms4.617 ms4.577 ms0.388 ms1.957 ms7.981 ms
bm_tracker12.776 ms11.816 ms12.449 ms11.755 ms11.762 ms11.983 ms11.764 ms
bm_tracker_flat2.935 ms2.517 ms2.374 ms2.264 ms2.250 ms2.261 ms2.258 ms
bm_xapian9.292 ms2.702 ms10.573 ms6.773 ms3.098 ms11.438 ms3.035 ms
rating:[90 TO 99] - 17,251 movies, 260 matches
t1t2t3t4t5t6t7
bm_lucene++58.996 ms56.894 ms62.172 ms57.028 ms57.255 ms57.540 ms57.259 ms
bm_sqlite36.682 ms28.260 ms34.116 ms34.786 ms35.195 ms35.813 ms35.221 ms
bm_sqlite_index45.802 ms62.460 ms31.603 ms32.982 ms33.302 ms31.904 ms31.656 ms
bm_tracker67.022 ms64.609 ms64.649 ms65.243 ms64.183 ms64.887 ms64.283 ms
bm_tracker_flat14.730 ms14.179 ms14.132 ms14.221 ms14.248 ms20.225 ms35.888 ms
bm_xapian94.872 ms47.067 ms85.202 ms28.575 ms142.854 ms48.562 ms52.567 ms
rating:[90 TO 99] - 121,587 movies, 1,510 matches
t1t2t3t4t5t6t7
bm_lucene++283.122 ms392.801 ms382.164 ms403.929 ms384.512 ms408.292 ms361.548 ms
bm_sqlite293.488 ms236.636 ms249.677 ms232.674 ms270.198 ms282.806 ms218.726 ms
bm_sqlite_index231.638 ms311.523 ms198.781 ms279.063 ms219.294 ms192.589 ms276.822 ms
bm_tracker-------
bm_tracker_flat181.478 ms272.453 ms251.730 ms256.744 ms293.067 ms230.615 ms245.113 ms
bm_xapian376.176 ms417.637 ms411.263 ms366.596 ms393.168 ms372.888 ms412.411 ms
release:[1999/01/01 TO 1999/09/30] - 9 movies, 2 matches
t1t2t3t4t5t6t7
bm_lucene++18.768 ms10.167 ms10.799 ms10.215 ms10.443 ms10.917 ms10.210 ms
bm_sqlite0.165 ms0.166 ms0.164 ms0.164 ms0.168 ms0.164 ms0.164 ms
bm_sqlite_index0.175 ms0.175 ms0.170 ms0.169 ms0.169 ms0.169 ms0.170 ms
bm_tracker1.074 ms0.569 ms0.546 ms0.561 ms0.544 ms0.549 ms0.546 ms
bm_tracker_flat0.877 ms0.480 ms0.460 ms0.458 ms0.461 ms0.458 ms0.456 ms
bm_xapian0.183 ms0.175 ms0.175 ms0.178 ms0.178 ms0.180 ms0.175 ms
release:[1999/01/01 TO 1999/09/30] - 1,099 movies, 34 matches
t1t2t3t4t5t6t7
bm_lucene++19.154 ms19.449 ms18.811 ms19.419 ms19.692 ms19.315 ms18.862 ms
bm_sqlite0.691 ms0.686 ms0.684 ms0.687 ms0.690 ms0.702 ms0.698 ms
bm_sqlite_index0.365 ms0.311 ms0.317 ms0.312 ms0.311 ms0.312 ms0.313 ms
bm_tracker6.231 ms5.543 ms5.734 ms5.522 ms5.663 ms5.538 ms5.465 ms
bm_tracker_flat1.998 ms1.494 ms1.466 ms1.469 ms1.470 ms1.454 ms1.469 ms
bm_xapian5.336 ms1.590 ms7.241 ms1.977 ms2.651 ms4.013 ms2.544 ms
release:[1999/01/01 TO 1999/09/30] - 3,216 movies, 84 matches
t1t2t3t4t5t6t7
bm_lucene++32.202 ms31.513 ms31.362 ms30.894 ms31.345 ms31.741 ms31.518 ms
bm_sqlite6.169 ms2.645 ms7.560 ms20.764 ms10.385 ms13.278 ms10.206 ms
bm_sqlite_index19.176 ms4.358 ms12.576 ms15.448 ms15.745 ms5.572 ms5.770 ms
bm_tracker15.507 ms14.803 ms13.629 ms15.465 ms13.930 ms14.515 ms13.652 ms
bm_tracker_flat3.956 ms3.488 ms3.183 ms3.176 ms3.213 ms3.193 ms3.157 ms
bm_xapian18.414 ms5.874 ms11.902 ms12.932 ms19.995 ms21.098 ms13.009 ms
release:[1999/01/01 TO 1999/09/30] - 17,251 movies, 374 matches
t1t2t3t4t5t6t7
bm_lucene++93.892 ms93.900 ms93.549 ms93.555 ms93.924 ms94.396 ms93.795 ms
bm_sqlite37.831 ms44.905 ms47.617 ms45.894 ms43.796 ms45.752 ms47.048 ms
bm_sqlite_index48.475 ms47.805 ms43.046 ms47.393 ms44.689 ms47.842 ms54.208 ms
bm_tracker72.507 ms72.667 ms72.233 ms73.570 ms72.997 ms72.991 ms72.527 ms
bm_tracker_flat29.351 ms48.892 ms55.351 ms49.793 ms88.375 ms55.393 ms45.917 ms
bm_xapian59.522 ms168.591 ms55.750 ms83.424 ms113.679 ms62.803 ms127.895 ms
release:[1999/01/01 TO 1999/09/30] - 121,587 movies, 2,265 matches
t1t2t3t4t5t6t7
bm_lucene++543.495 ms564.582 ms609.045 ms519.248 ms561.844 ms663.549 ms590.518 ms
bm_sqlite165.617 ms387.256 ms293.285 ms335.219 ms324.528 ms324.022 ms371.839 ms
bm_sqlite_index375.504 ms315.671 ms321.115 ms371.228 ms300.951 ms344.073 ms356.366 ms
bm_tracker-------
bm_tracker_flat241.569 ms316.626 ms398.308 ms349.426 ms398.289 ms318.078 ms363.809 ms
bm_xapian529.377 ms556.989 ms577.643 ms576.194 ms626.388 ms545.251 ms570.695 ms
release=1999/03/31 - 9 movies, 1 matches
t1t2t3t4t5t6t7
bm_lucene++10.065 ms10.068 ms9.702 ms9.974 ms9.837 ms9.751 ms10.356 ms
bm_sqlite0.164 ms0.165 ms0.171 ms0.168 ms0.167 ms0.164 ms0.162 ms
bm_sqlite_index0.171 ms0.169 ms0.171 ms0.172 ms0.175 ms0.165 ms0.164 ms
bm_tracker0.659 ms0.476 ms0.473 ms0.469 ms0.464 ms0.468 ms0.468 ms
bm_tracker_flat0.510 ms0.395 ms0.385 ms0.384 ms0.389 ms0.383 ms0.389 ms
bm_xapian0.154 ms0.152 ms0.151 ms0.153 ms0.152 ms0.156 ms0.152 ms
release=1999/03/31 - 1,099 movies, 2 matches
t1t2t3t4t5t6t7
bm_lucene++10.853 ms10.545 ms10.718 ms10.390 ms10.521 ms10.754 ms10.661 ms
bm_sqlite0.515 ms0.528 ms0.505 ms0.512 ms0.502 ms0.507 ms0.505 ms
bm_sqlite_index3.139 ms0.184 ms0.175 ms3.440 ms0.183 ms0.212 ms0.205 ms
bm_tracker4.559 ms4.229 ms4.177 ms4.220 ms4.383 ms4.532 ms4.464 ms
bm_tracker_flat0.977 ms0.830 ms0.800 ms0.808 ms0.802 ms0.811 ms0.802 ms
bm_xapian0.672 ms0.685 ms0.774 ms0.752 ms0.916 ms1.285 ms0.663 ms
release=1999/03/31 - 3,216 movies, 2 matches
t1t2t3t4t5t6t7
bm_lucene++10.799 ms10.762 ms11.399 ms10.676 ms10.704 ms10.169 ms10.325 ms
bm_sqlite1.912 ms1.462 ms1.453 ms1.163 ms1.151 ms1.157 ms4.858 ms
bm_sqlite_index0.366 ms0.350 ms0.355 ms1.883 ms0.364 ms0.345 ms0.371 ms
bm_tracker11.707 ms11.548 ms11.433 ms11.425 ms11.465 ms11.450 ms11.912 ms
bm_tracker_flat1.661 ms1.511 ms1.513 ms1.714 ms1.507 ms1.612 ms1.510 ms
bm_xapian1.278 ms1.364 ms1.359 ms1.821 ms1.994 ms1.429 ms3.192 ms
release=1999/03/31 - 17,251 movies, 3 matches
t1t2t3t4t5t6t7
bm_lucene++12.485 ms12.281 ms12.323 ms11.981 ms12.137 ms11.808 ms12.552 ms
bm_sqlite8.247 ms6.259 ms6.007 ms6.300 ms6.125 ms5.958 ms5.921 ms
bm_sqlite_index0.379 ms0.297 ms0.285 ms0.284 ms0.252 ms0.254 ms0.251 ms
bm_tracker61.537 ms60.815 ms61.014 ms60.821 ms61.013 ms60.850 ms60.820 ms
bm_tracker_flat11.063 ms8.021 ms8.414 ms8.690 ms7.798 ms7.811 ms8.313 ms
bm_xapian5.545 ms4.561 ms4.956 ms4.388 ms4.321 ms4.687 ms4.396 ms
release=1999/03/31 - 121,587 movies, 12 matches
t1t2t3t4t5t6t7
bm_lucene++14.005 ms14.031 ms12.792 ms14.354 ms12.736 ms13.862 ms13.374 ms
bm_sqlite64.517 ms61.783 ms61.669 ms62.418 ms61.377 ms61.326 ms62.036 ms
bm_sqlite_index9.994 ms0.403 ms0.358 ms0.351 ms0.368 ms0.363 ms3.368 ms
bm_tracker-------
bm_tracker_flat62.160 ms62.760 ms56.630 ms60.929 ms54.310 ms53.189 ms58.016 ms
bm_xapian29.180 ms28.239 ms28.080 ms28.054 ms27.777 ms27.615 ms27.505 ms
title=The Matrix - 9 movies, 1 matches
t1t2t3t4t5t6t7
bm_lucene++9.248 ms8.929 ms9.139 ms9.455 ms9.609 ms9.128 ms9.110 ms
bm_sqlite0.163 ms0.163 ms0.163 ms0.161 ms0.160 ms0.163 ms0.164 ms
bm_sqlite_index0.167 ms0.165 ms0.178 ms0.164 ms0.164 ms0.163 ms0.165 ms
bm_tracker0.733 ms0.484 ms0.475 ms0.478 ms0.481 ms0.475 ms0.476 ms
bm_tracker_flat0.575 ms0.400 ms0.380 ms0.382 ms0.379 ms0.387 ms0.379 ms
bm_xapian0.226 ms0.197 ms0.194 ms0.191 ms0.191 ms0.194 ms0.190 ms
title=The Matrix - 1,099 movies, 1 matches
t1t2t3t4t5t6t7
bm_lucene++10.758 ms10.578 ms10.083 ms10.230 ms10.555 ms10.630 ms10.831 ms
bm_sqlite0.728 ms0.524 ms0.504 ms0.501 ms0.506 ms0.500 ms0.501 ms
bm_sqlite_index0.218 ms0.203 ms0.201 ms0.198 ms0.199 ms0.277 ms0.233 ms
bm_tracker5.906 ms5.409 ms5.426 ms5.453 ms5.420 ms5.410 ms5.344 ms
bm_tracker_flat1.685 ms1.471 ms1.455 ms1.455 ms1.440 ms1.448 ms1.439 ms
bm_xapian0.445 ms0.385 ms0.398 ms0.373 ms0.836 ms0.451 ms0.374 ms
title=The Matrix - 3,216 movies, 1 matches
t1t2t3t4t5t6t7
bm_lucene++10.138 ms10.144 ms10.652 ms10.124 ms10.169 ms10.070 ms10.547 ms
bm_sqlite2.587 ms1.180 ms1.198 ms2.202 ms1.411 ms1.422 ms1.288 ms
bm_sqlite_index0.323 ms0.300 ms0.306 ms0.298 ms0.493 ms0.304 ms0.304 ms
bm_tracker15.097 ms14.727 ms14.692 ms14.759 ms14.840 ms14.888 ms14.791 ms
bm_tracker_flat3.727 ms3.529 ms3.558 ms3.545 ms3.504 ms3.504 ms3.520 ms
bm_xapian0.432 ms0.353 ms0.345 ms0.349 ms0.348 ms0.342 ms0.692 ms
title=The Matrix - 17,251 movies, 1 matches
t1t2t3t4t5t6t7
bm_lucene++12.462 ms11.871 ms12.020 ms11.603 ms12.469 ms11.850 ms11.823 ms
bm_sqlite6.093 ms6.096 ms6.130 ms5.941 ms5.882 ms5.959 ms6.789 ms
bm_sqlite_index1.431 ms0.304 ms0.201 ms0.200 ms0.201 ms0.199 ms0.199 ms
bm_tracker79.019 ms78.831 ms78.514 ms78.491 ms79.423 ms78.506 ms78.759 ms
bm_tracker_flat19.173 ms20.160 ms19.373 ms19.043 ms18.992 ms18.961 ms19.207 ms
bm_xapian0.422 ms0.344 ms0.339 ms0.335 ms0.336 ms0.339 ms0.345 ms
title=The Matrix - 121,587 movies, 1 matches
t1t2t3t4t5t6t7
bm_lucene++13.367 ms13.395 ms12.906 ms13.164 ms12.856 ms13.348 ms12.862 ms
bm_sqlite62.625 ms61.341 ms61.296 ms61.361 ms61.248 ms61.195 ms61.607 ms
bm_sqlite_index0.328 ms0.312 ms0.300 ms0.303 ms0.301 ms7.473 ms0.330 ms
bm_tracker-------
bm_tracker_flat138.148 ms131.762 ms130.937 ms131.431 ms131.471 ms130.975 ms130.770 ms
bm_xapian0.833 ms0.681 ms0.674 ms0.687 ms0.665 ms0.667 ms0.665 ms
director=Quentin Tarantino - 9 movies, 1 matches
t1t2t3t4t5t6t7
bm_lucene++9.112 ms9.540 ms9.671 ms9.258 ms9.510 ms9.597 ms9.126 ms
bm_sqlite0.273 ms0.243 ms0.243 ms0.241 ms0.239 ms0.239 ms0.239 ms
bm_sqlite_index0.282 ms0.243 ms0.257 ms0.244 ms0.245 ms0.243 ms0.337 ms
bm_tracker0.810 ms0.547 ms0.542 ms0.544 ms0.541 ms0.554 ms0.567 ms
bm_tracker_flat0.606 ms0.410 ms0.398 ms0.403 ms0.383 ms0.459 ms0.392 ms
bm_xapian0.215 ms0.204 ms0.195 ms0.197 ms0.195 ms0.208 ms0.194 ms
director=Quentin Tarantino - 1,099 movies, 9 matches
t1t2t3t4t5t6t7
bm_lucene++11.574 ms12.063 ms11.780 ms12.169 ms12.253 ms11.801 ms11.939 ms
bm_sqlite13.775 ms8.831 ms9.583 ms9.506 ms9.193 ms9.154 ms9.452 ms
bm_sqlite_index13.332 ms8.963 ms10.201 ms9.064 ms8.925 ms10.095 ms8.756 ms
bm_tracker5.173 ms4.644 ms4.546 ms4.473 ms4.552 ms4.472 ms4.455 ms
bm_tracker_flat1.137 ms0.857 ms0.851 ms0.855 ms0.844 ms0.842 ms0.844 ms
bm_xapian0.898 ms0.878 ms0.893 ms0.873 ms1.000 ms0.882 ms0.843 ms
director=Quentin Tarantino - 3,216 movies, 10 matches
t1t2t3t4t5t6t7
bm_lucene++12.343 ms12.175 ms12.307 ms12.004 ms12.235 ms12.947 ms12.194 ms
bm_sqlite40.967 ms37.867 ms38.607 ms37.618 ms37.487 ms37.124 ms38.147 ms
bm_sqlite_index43.470 ms36.820 ms37.027 ms36.779 ms36.957 ms36.585 ms36.782 ms
bm_tracker13.707 ms13.074 ms12.763 ms12.740 ms12.848 ms12.779 ms12.855 ms
bm_tracker_flat2.015 ms1.559 ms1.531 ms1.525 ms1.530 ms1.545 ms1.511 ms
bm_xapian0.933 ms0.886 ms0.908 ms2.944 ms1.023 ms1.030 ms0.799 ms
director=Quentin Tarantino - 17,251 movies, 13 matches
t1t2t3t4t5t6t7
bm_lucene++13.704 ms14.413 ms14.331 ms15.096 ms14.026 ms14.492 ms14.205 ms
bm_sqlite307.961 ms308.146 ms308.565 ms307.942 ms308.342 ms308.387 ms308.991 ms
bm_sqlite_index308.011 ms305.433 ms305.347 ms304.567 ms304.920 ms305.567 ms304.404 ms
bm_tracker72.690 ms72.075 ms72.005 ms71.999 ms71.938 ms71.946 ms72.108 ms
bm_tracker_flat7.489 ms6.996 ms6.877 ms6.987 ms7.148 ms7.088 ms7.021 ms
bm_xapian1.087 ms0.963 ms1.010 ms1.151 ms1.088 ms0.965 ms0.959 ms
director=Quentin Tarantino - 121,587 movies, 14 matches
t1t2t3t4t5t6t7
bm_lucene++13.546 ms13.955 ms13.981 ms13.854 ms13.740 ms14.114 ms15.816 ms
bm_sqlite4,752.853 ms2,793.690 ms2,800.197 ms2,795.611 ms2,800.578 ms2,794.765 ms2,801.000 ms
bm_sqlite_index2,806.890 ms2,789.648 ms2,788.729 ms2,791.168 ms2,788.102 ms2,790.845 ms2,789.475 ms
bm_tracker-------
bm_tracker_flat47.801 ms46.303 ms46.701 ms46.640 ms46.467 ms46.862 ms46.448 ms
bm_xapian20.098 ms1.260 ms1.176 ms1.162 ms1.156 ms1.149 ms1.148 ms
T* - 9 movies, 9 matches
t1t2t3t4t5t6t7
bm_lucene++17.303 ms17.072 ms16.927 ms16.539 ms16.816 ms16.758 ms16.797 ms
bm_sqlite0.547 ms0.544 ms0.547 ms0.541 ms0.541 ms0.546 ms0.544 ms
bm_sqlite_index0.553 ms0.549 ms0.554 ms0.553 ms0.658 ms0.547 ms0.544 ms
bm_tracker-------
bm_tracker_flat2.525 ms2.302 ms2.423 ms2.415 ms2.372 ms2.356 ms2.305 ms
bm_xapian3.086 ms2.871 ms2.947 ms2.893 ms3.104 ms3.022 ms3.126 ms
T* - 1,099 movies, 1,098 matches
t1t2t3t4t5t6t7
bm_lucene++358.775 ms355.830 ms350.287 ms349.816 ms347.998 ms356.585 ms347.143 ms
bm_sqlite64.679 ms142.927 ms143.776 ms142.847 ms145.319 ms147.244 ms135.600 ms
bm_sqlite_index62.383 ms151.941 ms144.456 ms144.108 ms141.330 ms173.728 ms169.799 ms
bm_tracker-------
bm_tracker_flat199.108 ms213.355 ms202.793 ms196.659 ms194.937 ms194.708 ms195.267 ms
bm_xapian419.323 ms516.929 ms677.357 ms591.280 ms599.091 ms643.124 ms497.649 ms
T* - 3,216 movies, 3,204 matches
t1t2t3t4t5t6t7
bm_lucene++842.413 ms968.828 ms958.367 ms1,002.383 ms932.222 ms946.388 ms1,004.821 ms
bm_sqlite327.669 ms415.921 ms440.198 ms408.543 ms432.575 ms537.572 ms412.061 ms
bm_sqlite_index310.218 ms432.201 ms413.221 ms404.165 ms479.691 ms431.758 ms436.533 ms
bm_tracker-------
bm_tracker_flat727.867 ms711.970 ms722.046 ms717.685 ms719.927 ms713.077 ms713.843 ms
bm_xapian1,442.238 ms1,470.821 ms1,415.183 ms1,392.164 ms1,437.493 ms1,464.149 ms1,520.747 ms
T* - 17,251 movies, ≥ 10,000 matches
t1t2t3t4t5t6t7
bm_lucene++3,006.139 ms3,127.174 ms3,136.617 ms3,151.197 ms3,131.469 ms3,141.155 ms3,056.497 ms
bm_sqlite1,481.321 ms1,388.573 ms1,468.062 ms1,533.263 ms1,422.012 ms1,442.638 ms1,456.166 ms
bm_sqlite_index1,346.717 ms1,451.410 ms1,508.228 ms1,411.643 ms1,460.563 ms1,514.390 ms1,391.342 ms
bm_tracker-------
bm_tracker_flat2,945.536 ms2,938.230 ms2,957.149 ms2,959.569 ms2,972.291 ms2,933.668 ms2,936.655 ms
bm_xapian3,391.825 ms3,490.307 ms3,474.203 ms3,483.310 ms3,560.886 ms3,505.060 ms3,398.937 ms
T* - 121,587 movies, ≥ 10,000 matches
t1t2t3t4t5t6t7
bm_lucene++3,627.408 ms3,625.588 ms3,546.610 ms3,508.233 ms3,599.160 ms4,597.857 ms4,101.686 ms
bm_sqlite2,182.548 ms2,109.730 ms2,109.812 ms2,121.573 ms2,104.320 ms2,117.912 ms2,145.342 ms
bm_sqlite_index2,108.863 ms2,103.648 ms2,131.009 ms2,132.823 ms2,109.655 ms2,137.286 ms2,106.779 ms
bm_tracker-------
bm_tracker_flat8,757.130 ms9,316.640 ms8,708.298 ms8,781.584 ms8,788.042 ms8,699.770 ms8,721.099 ms
bm_xapian4,805.474 ms4,528.004 ms4,692.763 ms4,640.065 ms4,618.215 ms4,647.170 ms4,674.588 ms

by Mathias Hasselmann at April 25, 2012 07:48 AM

Planet Qt is made from the many different sources. The opinions it contains are those of the contributor.