Welcome back!
The empty file finder program works perfectly fine, but let's say it needs to process ten thousands
of files in a directory.
Let me show you how we can optimize it.
In this program,
everything is fine actually.
However, one thing that I can optimize is allocating the backing array of the names slice only once. As
you know, here,
the program appends to the names slice in a loop. Doing so allocates a new backing array whenever the
backing array becomes full.
Instead, I can calculate the required size of the slice once, so that it will allocate the backing array
only once. There are two ways to calculate the required size.
The first one is using a heuristic like the average file name lengths across file systems and then
multiplying it with the number of files inside the folder.
The second way is calculating exactly how many bytes the program is going to need
by looking at the name of the files. Let's take a look at the first way.
Here is a table for the maximum file name lengths across
common file systems. As you can see, on average it is 255 bytes.
By the way, a single byte doesn't necessarily mean a single character, a single character can be more
than one byte. However, to keep things simpler here,
I'm going to assume it like so.
OK, so I can multiply the number of files with this number 255 to find out the total required space.
OK
I'm also going to add a new line character after each file name. So, I'm going to add 1 to make it 256.
Remember: This is a nil slice. So, it doesn't have a backing array until the program appends to it.
But now, I've got the total required bytes, so I can allocate the backing array of the names slice once.
To do that,
I'm going to use the make function like so. Remember: When I give the length of 0 to the make function, I can
easily add new elements to the beginning of the slice (using append()).
Alright, let me run it, okay.
It works perfectly.
Now it allocates a backing array only once.
Let me show you the total allocated bytes for the names slice by printing the capacity of the slice,
like so.
Let me also show you the total written bytes to the out.txt file.
As you can see, I allocate an unnecessarily huge number of bytes.
I allocate about one and half thousand bytes but I save only 33 bytes to the output file.
To further optimize this,
now, let's take a look at the second way. As you can see, for each file in the folder I reserve 256 bytes,
no matter whether the file is empty or not.
Let's optimize it further by calculating the exact space required.
I can count the total length of every file name inside the folder to do that.
I need to double this very same loop, like this.
I don't know the total required bytes yet.
So let me declare the total variable here,
like so. Now I'm going to add the length of the next file name to the total like so. You know, the loop
below also adds a new line after each file name.
So I'm going to add one for the new line as well.
Okay let me rerun it.
As you can see, now the program only allocates 33 bytes and writes 33 bytes to the
file.
It is as efficient as it can be.
Actually, this optimization isn't vital because this is a batch program.
I mean a batch program runs only once,
then it quits.
However, sometimes you can use the same code in a long-running program such as a server. Especially for
that case,
you might want to optimize it as I did here.
Otherwise, as I said before, you can trust the append function,
most of the time...
All right.
That's all for now.
Thank you for watching so far. Bye!