Monday, April 16, 2007

Childhood Memories

Today, Miguel asked me to take a look at fixing some of the System.Console 2.0 bugs. I managed to fix some of the ReadKey() and ReadLine() bugs, although the Backspace bug illustrated in Iron Python is still out there (it appears that the cursor X,Y position is not correctly kept track of in Mono).

Earlier today, when Miguel was explaining to me what sorts of problems existed in System.Console, one of the things he was hoping I could take a look at (although there was no bug # that I know of?) was optimizing Console.Write[Line]().

I didn't actually have time to look at that until tonight when I was sitting at my home computer waiting for my dinner to finish cooking. The solution was fairly simple (for those interested in seeing the patch, check out revision 75806).

An important part of optimizing a section of code is to compare actual running times of the old code vs the new code (and, obviously, to check that the results are correct), so I wrote a simple program that could be measured for performance improvements:

using System;

public class Program {
    static void Main () {
        Console.ForegroundColor = ConsoleColor.Cyan;
        string abc = new String ('a', 100000);
        Console.WriteLine (abc);

Using the system `time' command, I got the following times:

pre optimization:

real 0m13.177s
user 0m0.308s
sys 0m0.232s

post optimization:

real 0m0.238s
user 0m0.124s
sys 0m0.004s


Anyways, the reason the title of this blog is "Childhood Memories" is because after running this test program, I couldn't help but remember my first assembler program for the 6502 that I wrote back when I was 8 years old - it was a program which filled the screen with the character 'A' (which I then compared to a program written in BASIC that did the same thing). The difference in speed here was about the same as it was back then, too, funnily enough :)

Update: This morning I woke up realizing that I had a bug in my optimization patch last night, but I had a fix that lost no performance and then later today (in part thanks to Alan's prompting me to re-evaluate my need for a temporary buffer, which truly became unnecessary after my fix this morning) was able to optimize it even further (and eliminated the need for a temporary buffer) by blitting chunks of the input buffer between special escape sequences at a time (we have to handle certain escape sequences specially as they can relocate the cursor).

Oh, and the Iron Python bug is now solved... it was actually arguably a bug in Iron Python in that it goes behind Mono's back when writing to stdout so it was impossible for us to keep track of the cursor position. They do, however, use Console.In.ReadLine() (would be better if they simply used Console.ReadLine() but I digress), and so what I did was make ReadLine() query the terminal for the cursor position (rather than rely on our own state).

Friday, April 13, 2007

Refactory Operations

I think I'm finally finished hacking on the Navigation History feature in MonoDevelop, which started off as more-or-less a direct rip-off of the one in SharpDevelop, but quickly began incorporating improvement ideas from Miguel, Lluis, and myself.

Now on to bigger and more exciting things... namely, refactory features.

A few weeks ago I had taken a look at some of Microsoft's Visual Studio 2005's and SharpDevelop's context-menu-based refactoring functions and have just stubbed a few of them out in current MonoDevelop svn (added the Rename and Implement Interface items):

In the above screenshot, you can see the menu we get when right-clicking on the name of an interface in a class definition.

Here, I right-clicked on the name of the class in the class definition.

Going forward, I'll be looking at the refactoring functionality that Eclipse provides along with Intellij's, ReSharper's and Refactor Pro's features.

So far I've really only had time to watch the Refactor Pro demos. They are pretty awesome, but I think the UI bits (at least) are a bit over the top. Certainly not going to be easy to implement. I'll probably be looking at easier approaches.

Thursday, April 12, 2007

GMime is damn fast

Came across this in the zsh archives:

I've been using the stand-alone:

I never realised I already had it in openssl.
Thanks for the tip.

This led me to see what else I might already have or could get in a ready made package rather than having to use a source. (I do need this util in some form on every box and previously all my boxes were SCO OpenServer and I had been using the fourmilab source for years.)

Then I decided to run a few simple time tests, since this gets used a lot in various system() commands in application code and cgi scripts etc...

I expected the simple plain base64 util to be the fastest but I was wrong:

In each case I repeated the same command many times and always got almost exactly the same results, that is, +- 0m0.004 of the numbers shown so these are representative not just a fluke or caching effects or effects of the os being busy elsewhere.

the fourmilab source:
nj4:~ # time base64 </boot/vmlinuz >/dev/null

real    0m0.074s
user    0m0.072s
sys     0m0.000s

nj4:~ # time opsnssl base64 </boot/vmlinuz >/dev/null
-bash: opsnssl: command not found

real    0m0.001s
user    0m0.000s
sys     0m0.000s

mimencode comes in the metamail package:
nj4:~ # time mimencode </boot/vmlinuz >/dev/null

real    0m0.078s
user    0m0.076s
sys     0m0.004s


It actually does base64 not uuencode if you give it the -m or --base64 option.

It comes in the gmime package.

It prepends and appends some junk to the actual base64 output so it's inconvenient for me to actually use:

   nj4:~ # echo this is a test |gmime-uuencode -m -
   begin-base64 600 -
   nj4:~ #
As for the speed:
nj4:~ # time gmime-uuencode -m - </boot/vmlinuz >/dev/null

real    0m0.009s
user    0m0.008s
sys     0m0.000s

Ooenssl destroys the rest.

So even though I have the dedicated util it's actually better to use openssl.

As a side benefit, thats one less special thing to maintain on all my boxes.

The funny thing here is that `opsnssl` doesn't even exist, so his performance comparison is kinda... well, non-existent. It's still interesting, though, because `gmime-uuencode -m` can encode the file almost as fast as it takes the system to realize that opsnssl doesn't exist!

I find it amusing that at the end of his comparison section, he spells OpenSSL wrong yet again ("Ooenssl").

Good stuff ;-)

Anyways... we've probably all made goofs like this. I mostly found it amusing because of how awesome GMime is :p

Saturday, April 7, 2007

New Bike

Just got back from picking up my new bike... got a Specialized Allez Elite Double:

Spent the extra money for rim upgrades as well (Roval Pavel SL's).

Monday, April 2, 2007

Another One Bites the Dust

Woke up this morning, went to get some breakfast in the kitchen and then heard this really odd whirring sound. At first I thought it was coming from outside, but as I started moving toward my window I passed by my desk and could definitely tell it was coming from my laptop. Sure enough, my laptop's hard drive was the culprit, so I immediately turned the computer off in the hope that I might be able to save my data later if I shut it down soon enough.

I've known I was going to need a new laptop sometime this year for a while (it's over 3 years old now), but I was hoping that I'd have gotten a new laptop before this one died so suddenly so that I could avoid losing all my data. Oh well...

Now I gotta make up my mind, do I want to go for a Lenovo T60 (my current one was a an IBM T40)? Or do I want to try a Macbook?

Code Snippet Licensing

All code posted to this blog is licensed under the MIT/X11 license unless otherwise stated in the post itself.