HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Optimize DriveSpace Checker

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
checkeroptimizedrivespace

Problem

I recently wrote my first C# app that's goal it to take a drive letter and output a CSV list of some basic information. TOTALSPACE,FREESPACE,STATUS.

I've been wondering If it would be possible to make this application even faster. Got any good suggestions?

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace drivespace
{
class Program
{
    static void Main(string[] args)
    {
       //"PATHTOEXE\drivespace.exe" drive-C:
        foreach (String arg in args)
        {
            String[] parts = arg.Split('-');
            if (parts[0].Equals("drive"))
            {
                long toalspace = 0;
                long freespace = 0;
                string status = "NOTFOUND";

                foreach (DriveInfo drive in DriveInfo.GetDrives())
                {
                    if (drive.Name == parts[1] + ":\\")
                    {
                        if (drive.IsReady)
                        {
                            toalspace = drive.TotalSize;
                            freespace = drive.TotalFreeSpace;
                            status = "READY";
                        }
                        else
                        {
                            status = "NOTREADY";
                        }
                        break;
                    }
                }
                //TOTALSPACE,FREESPACE,STATUS
                Console.WriteLine(toalspace.ToString() + "," + freespace.ToString() + ',' + status);
            }
        }
    }
}
}


https://github.com/keverw/drivespace is the Github page, it might have some more useful info.

Solution

It is possible to make the application faster (but I am not sure that you will notice the difference unless you call the application with many arguments and have many drives). The main problem with the code is that you iterate through all the arguments, and for each argument you iterate through all the drives until you find the matching drive-letter.

So if the the application is called with an unknown drive-letter 10 times (as in "PATHTOEXE\drivespace.exe" drive-X drive-X drive-X drive-X ... and if you have 15 drives mounted, then DriveInfo.GetDrives() will be called 10 times and the line if (drive.Name == parts[1] + ":\\") will be executed 150 times. To avoid this you could store the drive information in a dictionary and then just lookup the matching drive in near constant time.

Notice below that I have changed the format of the arguments to the application to DriveSpace.exe C D X to avoid the parsing of the individual argument.

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Drivespace
{
    class Program
    {
        static void Main(string[] args)
        {
            var allDrives = DriveInfo.GetDrives().ToDictionary(drive => drive.Name);

            foreach (String arg in args)
            {
                DriveInfo driveInfo;
                if (allDrives.TryGetValue(arg + @":\", out driveInfo))
                {
                    if (driveInfo.IsReady)
                    {
                        WriteOutput(driveInfo.TotalSize, driveInfo.TotalFreeSpace, "READY");
                    }
                    else
                    {
                        WriteOutput(0, 0, "NOTREADY");
                    }
                }
                else
                {
                    WriteOutput(0, 0, "NOTFOUND");
                }
            }
        }

        private static void WriteOutput(long totalSize, long freeSpace, string status)
        {
            Console.WriteLine(String.Format("{0},{1},{2}", totalSize, freeSpace, status));
        }
    }
}

Code Snippets

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Drivespace
{
    class Program
    {
        static void Main(string[] args)
        {
            var allDrives = DriveInfo.GetDrives().ToDictionary(drive => drive.Name);

            foreach (String arg in args)
            {
                DriveInfo driveInfo;
                if (allDrives.TryGetValue(arg + @":\", out driveInfo))
                {
                    if (driveInfo.IsReady)
                    {
                        WriteOutput(driveInfo.TotalSize, driveInfo.TotalFreeSpace, "READY");
                    }
                    else
                    {
                        WriteOutput(0, 0, "NOTREADY");
                    }
                }
                else
                {
                    WriteOutput(0, 0, "NOTFOUND");
                }
            }
        }

        private static void WriteOutput(long totalSize, long freeSpace, string status)
        {
            Console.WriteLine(String.Format("{0},{1},{2}", totalSize, freeSpace, status));
        }
    }
}

Context

StackExchange Code Review Q#11498, answer score: 2

Revisions (0)

No revisions yet.