Wednesday, 30 December 2009

Two cool Christmas presents

Christmas has always been a special time for me, and now it's also special for the kids too.
This year my sister generously bought me a new car…
Super Grover in his convertible car
Pretty neat huh?
Carson got given this electronic robot.
Electronic robot
It came as a kit, which meant I had to pull out my trusty old soldering iron and solder all the components onto the PCB then assembly all the gearbox bits. I seem to recall my success rate for soldering electronic kits wasn't very good, but I'm pleased to report I managed to get this one working first time. Probably a good thing as I would have no idea how to fix it if it hadn't worked!
When you turn it on, it runs around the floor, and changes direction when the IR sensors detect an object in the way.
Merry Christmas and a Happy New Year to everyone.

Thursday, 17 December 2009

Watching the .NET Garbage Collector

Here's an interesting use of SciTech's .NET Memory Profiler – watching how objects are handled by the .NET CLR garbage collector.

The sample code create 4 objects – a simple class "Simple", a class that implements IDisposable "Disposable", and a class that also implements a destructor "Destructable".

.NET Memory Profiler can generate a real-time graph of memory allocations. I've instrumented the sample code using SciTech's API to add comments to the graph so you can match the code execution path against the X axis (time). The object instance count is mapped to the Y axis.

image

See how 2 instances of the "Destructable" class existed around the 10 second mark – then one was released at the first GC, then the 2nd (which has the destructor) is only released after the 2nd GC.

using System;
using System.Diagnostics;
using SciTech.NetMemProfiler;

namespace MemoryTesting
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            MemProfiler.FullSnapShot("Start");

            CreateSimple();

            CreateDisposable();
            System.Threading.Thread.Sleep(1000);

            CreateDestructableAndDispose();
            System.Threading.Thread.Sleep(1000);

            CreateDestructable();
            System.Threading.Thread.Sleep(1000);

            MemProfiler.AddRealTimeComment("GC");
            GC.Collect();

            System.Threading.Thread.Sleep(2000);
            MemProfiler.AddRealTimeComment("WaitForPendingFinalizers");
            GC.WaitForPendingFinalizers();

            System.Threading.Thread.Sleep(2000);

            MemProfiler.AddRealTimeComment("GC");
            GC.Collect();

            System.Threading.Thread.Sleep(1000);

            MemProfiler.AddRealTimeComment("End");
            MemProfiler.FullSnapShot();

        }

        private static void CreateSimple()
        {
            MemProfiler.AddRealTimeComment("Create Simple");

            var a = new Simple();
            a.Something += OnEventHandler;
            a.Data = "hey";

            a.Something -= OnEventHandler;

        }

        private static void CreateDisposable()
        {
            MemProfiler.AddRealTimeComment("Create Disposable");

            var a = new Disposable();
            a.Something += OnEventHandler;
            a.Data = "ho";
            System.Threading.Thread.Sleep(1000);
            a.Something -= OnEventHandler;

            a.Dispose();
        }

        private static void CreateDestructableAndDispose()
        {
            MemProfiler.AddRealTimeComment("Create Destructable and Dispose");

            var a = new Destructable();
            a.Something += OnEventHandler;
            a.Data = "haha";
            System.Threading.Thread.Sleep(1000);
            a.Something -= OnEventHandler;

            a.Dispose();
        }

        private static void CreateDestructable()
        {
            MemProfiler.AddRealTimeComment("Create Destructable");

            var a = new Destructable();
            a.Something += OnEventHandler;
            a.Data = "haha";
            System.Threading.Thread.Sleep(1000);
            a.Something -= OnEventHandler;
            //a.Dispose();
        }

        private static void OnEventHandler(object sender, EventArgs e)
        {
            Debug.WriteLine("Something Fired");
        }
    }

    public class Simple
    {
        private string _data;

        public string Data
        {
            get { return _data; }
            set
            {
                _data = value;
                OnSomething(null);
            }
        }

        public event EventHandler Something;

        protected virtual void OnSomething(EventArgs e)
        {
            EventHandler handler = Something;
            if (handler != null) handler(this, e);
        }
    }


    public class Disposable : Simple, IDisposable
    {
        #region IDisposable Members

        public void Dispose()
        {
            System.Threading.Thread.Sleep(1000);

            MemProfiler.AddRealTimeComment("Dispose");

            Dispose(true);
            GC.SuppressFinalize(this);
        }

        #endregion

        protected virtual void Dispose(bool disposing)
        {
        }
    }

    public class Destructable : Disposable
    {
        ~Destructable()
        {
            System.Threading.Thread.Sleep(1000);

            MemProfiler.AddRealTimeComment("Destructing");

            Dispose(false);
        }
    }
}

Tuesday, 8 December 2009

Time

The Byrds were spot on when they sang "To everything… there is a season… and a time to every purpose under heaven". Spot on, because the lyrics (whilst put to music by Pete Seeger according to Wikipedia) are actually adapted directly from Ecclesiastes 3.

Particularly appropriate for me at the moment is the line the following line:

"A right time to plant and another to reap" Ecc 3:2b (The Message)

r160170_602465[1]Right now in country areas of South Australia, harvest is in full swing. In the past that wouldn't have meant so much to me, but having worked for the last 18 months at a certain AustralianCanadian agribusiness, the change of seasons and especially the impact of weather on crop production has become much more relevant.

These are interesting, but exciting times. I'm sure a number of the other verses from Ecclesiastes 3 are also applicable at the moment, but I'll write more about that later!

Monday, 7 December 2009

Antihistamines

I've been a long-time hay fever sufferer. I also had a fair bit of allergic conjuctivitis in my younger years which I seem to be growing out of (finally!), though for the last 6 or so years dermographism has been a challenge too. You can just call me "Mr Healthy" :-)

Because of this, I have developed a more than average interest in antihistamines, and done a bit of research on the various "non-drowsy" over-the-counter products available in Australia.

The products are grouped by active ingredient, and then ordered by the most familiar brand name with that ingredient. As a rule, the best known brand is usually the most expensive – presumably you're paying extra for all the marketing and colourful packaging.

Brand Active Ingredient Size Dose Price Cost per tablet
Zyrtec Cetirizine 30 10mg 21.95 $ 0.73
Zodac Cetirizine 30 10mg 9.95 $ 0.33
Alzene Cetirizine 30 10mg 17.95 $ 0.60
Telfast Fexofenadine 30 180mg 22.95 $ 0.77
Xergic Fexofenadine 30 180mg 21.95 $ 0.73
Fexotabs Fexofenadine 50 180mg 26.45 $ 0.53
Fexal Fexofenadine 30 180mg 15.95 $ 0.53
Xyzal Levocetirizine 30 5mg 22.95 $ 0.77
Clarityne Loratadine 50 10mg 36.95 $ 0.74
Lorastyne Loratadine 50 10mg 21.95 $ 0.44
AllerEze Loratadine 50 10mg 27.95 $ 0.56
Chemists' Own Loratadine Loratadine 50 10mg 32.95 $ 0.66
Aerius Desloratadine 28 5mg 24.35 $ 0.87

Note also, the prices I've quoted here are from online pharmacies based in Australia, such as Pharmacy Direct and Pharmacy Online (don't forget to allow for postage). Buying the same identical product from a non-discount pharmacy may cost up to a 1/3 more.

I've tried all the main kinds, with varying degrees of success. I do think it is a good idea to swap products every few months as in my experience extended use of one specific antihistamine reduced its effectiveness (as though the body became desensitised to it).

Tuesday, 1 December 2009

A Sydney Wedding

Katie and Gabriel OsorioNarelle's cousin Katie was getting married in Sydney, so we bundled the family into a plane and headed over for the festivities.

I'd booked seats on Tiger Airways earlier in the year (taking advantage of particularly cheap tickets). One thing with Tiger is that everything besides a seat on the plane costs you extra. I paid for extra baggage allowance but decided not to shell out for the privilege of choosing allocated seats. There was a risk that Tiger's seat booking system might be so stupid that it could put the kids and the adults in completely separate seats, but I'm pleased to report that we ended up with decent seats all in the same row on both flights.

A few quibbles with Tiger – the PDF attachments they emailed me were blank. Fortunately I figured out that the attachment file name happened to be the confirmation number so you could still review the details by going to their Review Itinerary page. Their website also fails to mention the fact that they will carry prams for free (thanks to Margaret for finding that out).

I'm not sure if it's a measure of how trustworthy visitors to Sydney airport are, but you have to pay $4 to use a luggage cart – contrasted with Adelaide airport where the carts are free (and I'd suggest a better design too – 3 bags fit side-by-side which we couldn't do with the interstate model).

Not a Toyota Camry! I organised a hire car through http://www.airportrentacar.com.au/sydney/, who seemed to have the best price compared to some of the more familiar hire car companies. One thing I didn't find out until after submitting a hire request through their website was that they require a "CREDIT" credit card (ie. not a debit card) for security. So began a mad panic to try and obtain such a card in less that 2 weeks. Despite trying to ensure my credit union had all the paperwork required up front, it took a few days for them to ask me for a pay slip and then a group certificate. The Thursday of our departure arrived, but sadly the card did not (it was delivered the day before we got back home!) Thankfully Narelle's parents were also travelling on the same flight and were kind enough to use their card for the security (the actual payment could still be done on a debit card). Also in Sydney this company's office is actually within reasonable walking distance from the terminal. In peak hour if you don't have much luggage, walking may actually be faster than the free pickup they offer.

The car (a Toyota Camry Altise) was perfect for our needs, and we were able to just cram the kids into the back seat (with various booster/baby seats). Our own car is also a Camry (though a slightly older 1995 model) and by comparison I found the modern Altise quite responsive, a bit gruntier and with more headroom (something I tend to notice). Imagine my surprise to learn learn that the current model still has only a 4 cylinder engine. (And no, that picture is not a Camry!)

P1020144 P1020164We took the opportunity to do a bit of sight seeing, and visited Ocean World at Manly. We all enjoyed looking at all the various exhibits – especially walking through the tunnel through the aquarium. Boy those teeth look sharp!

Having grown up in Adelaide, driving in a big city like Sydney is not my idea of fun. The traffic just seems crazy, and it all feels like there are just way too many cars trying to squeeze along lots of too-narrow roads (even though the roads are usually multi-lane). At least this visit we did pretty well finding our way around – Narelle's old NSW navigation skills came through with flying colours.

It was a nice holiday but it is good to be home again.