star-hitran

Load line-by-line data from the HITRAN database
git clone git://git.meso-star.fr/star-hitran.git
Log | Files | Refs | README | LICENSE

commit 6ed4f0c790fa295897ff53ec7ae684e84602d373
parent 372d23022f0eb854716e8abf9aaa182ab5ecf9e6
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 12 Jan 2026 16:50:39 +0100

shtr: measures line access performance

Add the -a option, which activates the linear/random line access test
bench. As expected, decompression dominates access time, and random
access is three orders of magnitude slower than linear access.

Diffstat:
Mdoc/shtr.1 | 7+++++--
Msrc/shtr_main.c | 45++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/doc/shtr.1 b/doc/shtr.1 @@ -15,7 +15,7 @@ .\" .\" You should have received a copy of the GNU General Public License .\" along with this program. If not, see <http://www.gnu.org/licenses/>. -.Dd January 9, 2026 +.Dd January 12, 2026 .Dt SHTR 1 .Os .\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" @@ -25,7 +25,7 @@ .\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .Sh SYNOPSIS .Nm -.Op Fl hsv +.Op Fl ahsv .Op Fl l Ar lines .Op Fl m Ar molparam .Op Fl o Ar output @@ -75,6 +75,9 @@ The total memory used is finally printed. .Pp The options are as follows: .Bl -tag -width Ds +.It Fl a +Measure line access performance. +Both linear and random access are tested. .It Fl h Use suffixes to make memory usage easier to read: the number of consecutive digits is then three or less, using powers of 2 for sizes diff --git a/src/shtr_main.c b/src/shtr_main.c @@ -20,6 +20,7 @@ #include "shtr.h" +#include <rsys/clock_time.h> #include <rsys/cstr.h> #include <rsys/mem_allocator.h> #include <rsys/rsys.h> @@ -35,13 +36,14 @@ struct args { char* lines; char* output; + int bench_line_access; int internal_format; int verbose; /* Verbosity level */ int compression; /* Compression level */ int human_readable; }; static const struct args ARGS_DEFAULT = { - NULL, NULL, NULL, 0, 0, SHTR_DEFAULT_COMPRESSION, 0 + NULL, NULL, NULL, 0, 0, 0, SHTR_DEFAULT_COMPRESSION, 0 }; struct cmd { @@ -59,7 +61,7 @@ static INLINE void usage(FILE* stream) { fprintf(stream, -"usage: shtr [-hsv] [-l lines] [-m molparam] [-o output] [-z compression_level]\n"); +"usage: shtr [-ahsv] [-l lines] [-m molparam] [-o output] [-z compression_level]\n"); } static res_T @@ -72,8 +74,9 @@ args_init(struct args* args, int argc, char** argv) *args = ARGS_DEFAULT; - while((opt = getopt(argc, argv, "hl:m:o:svz:")) != -1) { + while((opt = getopt(argc, argv, "ahl:m:o:svz:")) != -1) { switch(opt) { + case 'a': args->bench_line_access = 1; break; case 'h': args->human_readable = 1; break; case 'l': args->lines = optarg; break; case 'm': args->molparam = optarg; break; @@ -250,6 +253,41 @@ error: goto exit; } +static void +bench_line_access(struct shtr_line_list* lines) +{ + struct shtr_line line; + struct time t0, t1; + const size_t random_read_count = 10000; + double lines_per_second = 0; + int64_t usec = 0; + size_t i, n; + + ASSERT(lines); + + SHTR(line_list_get_size(lines, &n)); + + /* Linear access */ + time_current(&t0); + FOR_EACH(i, 0, n) { + SHTR(line_list_at(lines, i, &line)); + } + usec = time_val(time_sub(&t0, time_current(&t1), &t0), TIME_USEC); + lines_per_second = 1.e9 * (double)n / (double)usec; + printf("linear access: %g lines per second\n", lines_per_second); + + /* Random access */ + time_current(&t0); + FOR_EACH(i, 0, random_read_count) { + const double r = (double)rand() / (double)(RAND_MAX-1); + const size_t iline = (size_t)(r * (double)n); + SHTR(line_list_at(lines, iline, &line)); + } + usec = time_val(time_sub(&t0, time_current(&t1), &t0), TIME_USEC); + lines_per_second = 1.e9 * (double)random_read_count / (double)usec; + printf("random access: %g lines per second\n", lines_per_second); +} + static res_T cmd_run(const struct cmd* cmd) { @@ -266,6 +304,7 @@ cmd_run(const struct cmd* cmd) if(cmd->args.lines) { if((res = load_lines(cmd, &lines)) != RES_OK) goto error; if((res = process_lines(cmd, lines)) != RES_OK) goto error; + if(cmd->args.bench_line_access) bench_line_access(lines); } sz = MEM_ALLOCATED_SIZE(&cmd->allocator);