The Raspberry Pi team provide an easy way of testing the performance of your SD card, or other storage media, with the Agnostics tool. The only downside is that it's a graphical tool, and if you want to test your SD card while running headless, or without a GUI, then you have to do a little hacking to get it to work.
Agnostics is a graphical wrapper and front end around the fio tool, with a specific test on read and write performance pre-configured. That means you still have to install fio first, before you can run the script that's in Agnostics, but other than that all pre-requisites should be present on even a lite install of the Raspberry Pi OS, to install:
$ sudo apt-get install fio
Then clone the project from Github into a local directory:
$ mkdir agnostics
$ git clone https://github.com/raspberrypi-ui/agnostics.git agnostics
In the data subdirectory you need to make a minor edit to the 'sdtest.sh' shell script file. If Agnostics is installed normally it will look for the sd_bench.fio file in directory /usr/share/agnostics, but since we've not installed it there, we have to update the path in the file so it looks in the correct place, which in this case is in the same data directory as the shell script.
On line 7, where it reads:
RES=$(fio --output-format=terse --max-jobs=4 /usr/share/agnostics/sd_bench.fio | cut -f 3,7,8,48,49 -d";" -)
change the line /usr/share/agnostics/sd_bench.fio
to read just sd_bench.fio
instead.
With that done you can run the script with
$ sh sdtest.sh
and see the results in the terminal.
You could use the fio tool directly to devise your own test, but it's sometimes useful to compare others' results using the same test, plus this way you get the targets the Pi team have devised for SD cards.
In my case I wanted to see if an old 32GB, class 4, SD card was better or worse than an old external USB hard drive. The answer is that both are bad, but in slightly different ways.
The SD card:
Run 1
prepare-file;0;0;5775;11
seq-write;0;0;5251;10
rand-4k-write;0;0;1093;273
rand-4k-read;4195;1048;0;0
Sequential write speed 5251 KB/sec (target 10000) - FAIL
Note that sequential write speed declines over time as a card is
used - your card may require reformatting
Random write speed 273 IOPS (target 500) - FAIL
Random read speed 1048 IOPS (target 1500) - FAIL
And the USB drive:
Run 1
prepare-file;0;0;26554;51
seq-write;0;0;27014;52
rand-4k-write;0;0;1622;405
rand-4k-read;525;131;0;0
Sequential write speed 27014 KB/sec (target 10000) - PASS
Random write speed 405 IOPS (target 500) - FAIL
Random read speed 131 IOPS (target 1500) - FAIL
(Runs 2 and 3 were not noticeable different for either device.)
So while the USB drive was better on two out of three measures, it was much worse on random read speed, and since this won't be used to write lots and lots of data, there doesn't seem to be real advantage in this scenario, in addition the USB drive requires additional external power as my Raspberry Pi can't supply the power iteself.