Chicken Scratches

Developing ideas on developing.
Page style (CSS):

Archive for February, 2008

When to use ToArray()

February 11th, 2008 by Eddie Sullivan

Some thoughts on when to return a List<> object and when to return an array in C#.

The analogy: strings

Many times in C#, a function that needs to build a string from constituent parts will use a StringBuilder internally, and then on the last line of the function call ToString() on the StringBuilder object. This is because strings in C# are immutable. That is, once they are set then can never be changed. Code that looks like it is changing a string in place is usually actually allocating a new string to hold the new value. Obviously, for a function that builds a string incrementally by constantly appending to it, this can lead to lots of reallocation, slowing down performance.

Here's an example of how it's normally done:

    public string GimmeString(int num)
    {
        StringBuilder sb = new StringBuilder("Initiating countdown: ");

        for (int i = num; i > 0; i--)
        {
            sb.Append(string.Format("{0}...", i));
        }
        sb.Append("Blastoff!\n");

        return sb.ToString();
    }
    

This is a pretty obvious design pattern. It's rare you would want to return the StringBuilder object itself, so almost always it is converted to a string before returning. The problem gets trickier, however, when we try to use a similar design pattern for arrays.

Arrays

Arrays in C# are not immutable, at least not in the way strings are. It could be said they are "partially immutable" (my own made-up term). You can swap out elements in the array as much as you like, but the array's length is fixed. Therefore, if you need to build up an array from constituent parts, it makes sense to use a List<> object for doing the work.

The analogy then becomes, in SAT terms:

StringBuilder : string :: List<> : array

The question then becomes whether or not to call ToArray() on the List<> before returning it. In this case, the answer's not as obvious. Let's examine the pros and cons of each approach:

Reasons to call ToArray()

  • If the returned value is not meant to be modified, returning it as an array makes that fact a bit clearer.
  • If the caller is expected to perform many non-sequential accesses to the data, there can be a performance benefit to an array over a List<>.
  • If you know you will need to pass the returned value to a third-party function that expects an array.
  • Compatibility with calling functions that need to work with .NET version 1 or 1.1. These versions don't have the List<> type (or any generic types, for that matter).

Reasons not to call ToArray()

  • If the caller ever does need to add or remove elements, a List<> is absolutely required.
  • The performance benefits are not necessarily guaranteed, especially if the caller is accessing the data in a sequential fashion. There is also the additional step of converting from List<> to array, which takes processing time.
  • The caller can always convert the list to an array themselves.

ToArray() or not ToArray()? That is the question.

Based on these points, it seems to make the most sense as a general rule to simply return the List<> object directly, rather than converting it to an array before returning. Let me know if you disagree.

Here's an example:

    // A contrived example. Similar to Python's "range" function, but only
    // supports positive step.
    public List<int> GimmeInts(int start, int end, int step)
    {
        List<int> ret = new List<int>();

        for (int i = start; i < end; i += step)
        {
            ret.Add(i);
        }
        // Here you could have:
        // return ret.ToArray();
        return ret;
    }
    

What’s wrong with hotels

February 8th, 2008 by Eddie Sullivan
Anybody who needs to stay in hotels often knows there are certain areas where they could all do better. I tend to look at everything with an eye towards what could be improved. Here are some random thoughts on how hotels could be better. Some of these ideas are a bit far-fetched, but hey, that's why I'm writing a weblog, not a manifesto.

More pricing logic

It sometimes seems like the cheaper a hotel is, the more services it provides. I've stayed in a broad range of hotels, from top of the line luxury suites to eight-cot-to-a-room hostels. Strangely, there are some areas where the lesser quality hotels actually do better. Why is it that when I pay $40 per night for a small family-run inn, there is personalized service and free wi-fi in every room, but in a hotel that charges $375 per night there is either no wi-fi available or it costs $20 extra? What are we actually getting for the higher price? Why do cheap hotels provide breakfast but expensive hotels don't? It's backwards.

Cleanliness

After seeing watching a news report about hotel cleanliness issues, I've been a little bit paranoid about sanitation in hotels. A couple idea:
Get rid of the carpet
Carpeted floors are notoriously hard to clean. I don't want to think about what kind of dirtiness people can leave on carpets that doesn't get picked up by a vacuum cleaner. Get rid of the carpeted floor. Replace it with hardwoods, or if that's too expensive, a synthetic material designed to not be too cold on our toes.
Auto-magically clean
Have you seen those coin-operated public restrooms in public cities that actually clean themselves after each use? Why can't we refine this technology and use it for hotel bathrooms? When the maid comes in, he or she removes all the towels and paper products, closes the bathroom door, and presses a button. Instantly, the whole bathroom is sprayed with disinfecting detergent from a nozzle in the ceiling, rinsed, then dried with high-speed air jets. Put the bed on hydraulic lifts to make it easy to clean underneath. Instead of just layering a blanket on top of a sheet, use a large pillow-case-like wrapper for the whole blanket. Design the quilt with drawstrings to make changing the blanket case easy. There is nothing worse than tossing around at night and waking to realize the sheet has slid off the bed and you're now face-to-face with someone else's potential filth.

Conveniences

This should be obvious, but: free wi-fi. For everyone. Everywhere. Provide an easy to use central control panel for things like the alarm clock, the thermostat, maybe even ordering room-service. Every hotel alarm clock has a different interface, leaving guests with no confidence they will actually wake up on time. Digital thermostats for the showers. It takes me forever to get the temperature just right in an unfamiliar shower. I want to be able to just turn a dial or press a button for the exact temperature I need and let the electronics do the rest.

And more

The more I think, the more ideas I come up with. I know most of these will never happen, but it can't hurt to dream, can it? Feel free to add any ideas using the comment link below.