Archive for September, 2011

Efficiency Over Elegance

What do you use when you want a server to communicate with a client over TCP? Some people would tell you to use HTTP. Some people would write their own binary protocol. A friend of mine is actively developing an IM client which communicates with a server using JSON. Unfortunately, some of this data needs to be raw binary, such as buddy icons, etc. Along with that, he uses JSON-framework for encoding and decoding.

JSON (JavaScript Object Notation), is a lightweight, human-readable way of representing dictionaries, arrays, strings, and numbers. For instance, a dictionary containing a single key might look something like this: ["myKey":999999]. You may immediately notice that the data could be smaller. There are two bytes already taken for the open and close brackets. Another two taken by the quotation marks. A few wasted bytes where a four-byte binary integer could be used to represent the number 999999. To some, this is fairly irrelevant. But consider the same amount of overhead for a very large amount of data. A more efficient binary storage method would be nice, and very handy to many.

I created a project called KeyedBits, a binary archive format. First I started off by writing a very simply Objective-C encoder and decoder that I called KBKit, which used some fancy object orientation to achieve its goal. Unfortunately, benchmarking this implementation gave unpromising results. Although it appears that KeyedBits saves an average of around 13%, KBKit was almost two times slower than JSON-framework. My natural reaction was not to optimize my Objective-C implementation, but to write another one in C.

I had already sacrificed the elegance and beauty of JSON, instead using a rather ugly binary format that only looks good when viewed in a hex editor. Now, I had to sacrifice the elegance of KBKit and instead write a C framework. For lack of a better name, I decided to call this C framework KBCKit.

It turns out that encoding was neck-and-neck between JSON-framework and KBKit. The real tie breaker was decoding. After I implemented both the encoder and decoder for KBCKit, and had written an Objective-C wrapper for each, I found that I was successful. KBCKit now is able to encode and decode almost twice as fast as JSON-framework. This, on top of the fact that there’s little overhead, makes KeyedBits a great alternative to JSON in Objective-C applications.

The lesson to be learned here is that sometimes beauty is not better than efficiency. Sure, my C implementation isn’t as fancy as my Objective-C implementation, but it certainly has a better end result. There are times when it’s okay to use a high-level language, but there are also times when it’s simply not appropriate. Imagine if the Linux kernel had been written in C++ instead of C. It would probably be a lot easier on the eyes, but ultimately easy on the eyes isn’t its purpose. Things like kernels, video decoders, and KBCKit were made to be used, not drawn on paper and hung in an art museum. The user doesn’t care how elegant the code is, they just want something with raw speed and power.

Applying Object-Oriented Programming

Recently I have been spending much time programming an operating system in C and assembly, using simple data structures and calling function after function.  I have decided to take a break from OS development, and instead work on some more high-level stuff in Objective-C.  I am currently working on an app called SuperLists, but today I wasn’t in the mood to work on an iPhone app.  Instead I decided to put some object-oriented programming to work in a mathematical expression parser.

A long while ago I wrote something very similar to this.  You can see the post for that here.  That expression parser didn’t correctly utilize the object-oriented programming model, and certainly wasn’t neat and organized.  The parser that I wrote today has the same final result as the old one, but is structured in a much better and more elegant way.

When parsing human readable text, the first thing your parser should do is convert a human-readable string into a data structure that the program can understand.  This stage is actually the definition of parsing, whereas calculating the result of the expression is known as evaluating.  So, I planned out a structure that would hold different operators, numbers, variables and functions.  This structure contains a base class, EPToken, with subclasses like EPOperator and EPNumericalToken.

After parsing the string given by the user, it is up to the evaluator to use the parsed tokens and calculate an end result.  The evaluator must follow the order of operations, whereas the parser simply reads the sequential tokens from the string.  To achieve this, the evaluator first recursively evaluates the “sub-expressions”, which are potential expressions contained within ( and ).  Next, all functions such as sin and sqrt are evaluated.  Finally, the evaluator evaluates different operators, such as ^, +, -, etc.

Every time a part of the expression is evaluated, that part is replaced by the numerical result.  For instance, when evaluating the ^ expression in 3x + 10^2 + sin(y), the result would be 3x + 100 + sin(y).  Once all operators, functions, and variables are evaluated, the only thing left in the expression should be a numerical constant.  This constant is the final result of the expression.

I finished the parser in only a few hours, and posted the code to a Github repository.  The project includes a demo of how to use my NSNumber additions to parse expressions with custom variables.  Custom functions can be used, but not when using the NSNumber convenience methods.

Messing with Launchpad on Lion

If you are not familiar, Apple has recently released a new operating system, namely Mac OS X Lion. This operating system comes with a “rich” set of features, including Apple’s new Launchpad, an iOS-like homescreen interface for launching and organizing applications. Most experienced (and some inexperienced) Mac users know that using something like Launchpad is rather pointless, but others (like myself) enjoy playing with all the new features of any software that has been upgraded.

Today, after I finished my installation of Lion, I immediately went ahead and examined the new features that I had been given. When I first opened Launchpad, I was horrified to see that every Application that I have in my “Applications” directory had already been dumped into the homescreen interface. Half of the apps in my Applications folder are pointless toys that I’ve made in Objective-C for personal use, some not even having icons. I struggled to figure out how to remove apps from this horrid homescreen, and to my amazement couldn’t accomplish even an obvious task such as this one.

After digging around, I discovered that Launchpad is actually part of the Dock, and therefore the Launchpad database is located at ~/Library/Application Support/Dock/. The ‘.db’ file located here holds an sqlite3 database which contains several tables that might be of interest. In terminal I did the following to figure out how this file is structured:

$ sqlite3 /Users/alex/Library/Application\ Support/Dock/2CC31627-90A0-4AE7-87D3-08AABCB92056.db 
SQLite version 3.6.23
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from sqlite_master;
...
table|apps|apps|4|CREATE TABLE apps (item_id INTEGER PRIMARY KEY,
title VARCHAR, bundleid VARCHAR, storeid VARCHAR,category_id INTEGER,
moddate REAL, bookmark BLOB)

So, there’s a table called ‘apps’ that seems to contain all of the apps stored in Launchpad. A select statement resulted as follows:

sqlite> SELECT * from apps;
226|Adium|com.adiumX.adiumX|||297296776.0|bookx
...
sqlite>

It became quite obvious to me that all I needed to do to remove all of the apps from Launchpad was to remove all of the items in this table. I proceeded to execute a delete statement:

sqlite> delete from apps where (1=1);

At first I assumed that this would do the trick, and threw up Launchpad. After seeing that all my apps where still there was they had been before, I thought of something. In a new terminal shell, I ran killall Dock. I watched as the desktop environment crumble under the non-existant foundation that used to be the Dock.  Then, as quickly as it had fallen, the desktop environment essentially rebooted itself, loading all of the configuration files from disk, including my modified Launchpad database.

Finally, to my satisfaction, it seemed that my apps had gone from Launchpad, leaving me with an empty slate onto which I could build. I began to drag all of the apps (that I actually use) from my Applications folder back into Launchpad.  Although I now have Launchpad configured to my liking, I don’t see myself using this as a method of launching my apps.  Most of the time the simple spotlight keystroke is a faster method of launching applications, and it would be pretty hard to make a faster alternative.

Return top