# include # include # include # include struct result { char city[100]; int count; double sum; double min; double max; }; int main ( int argc, const char **argv ); static int cmp ( const void *ptr_a, const void *ptr_b ); static int getcity ( const char *city, struct result results[], int nresults ); void timestamp ( ); /******************************************************************************/ int main ( int argc, const char **argv ) /******************************************************************************/ /* Purpose: 1brc_naive() is a naive solution of the one billion row challenge. Discussion: Modified: 12 May 2024 Author: Original C version by Danny van Kooten. This version by John Burkardt. */ { int c; FILE *fh; const char *file = "measurements.txt"; int i; double measurement; int nrecords; int nresults; struct result results[413]; clock_t tstart; clock_t tstop; timestamp ( ); printf ( "\n" ); printf ( "1brc_naive():\n" ); printf ( " C version.\n" ); printf ( " Carry out 1 Billion Row Challenge (1brc).\n" ); tstart = clock ( ); if ( 1 < argc ) { file = argv[1]; } /* Open the data file. */ fh = fopen ( file, "r" ); if ( ! fh ) { printf ( "\n" ); printf ( "1brc_naive(): Fatal error!\n" ); printf ( " Could not open file '%s'", file ); exit ( EXIT_FAILURE ); } printf ( " Reading file '%s'\n", file ); /* Read and process each record. */ nrecords = 0; nresults = 0; char buf[1 << 10]; while ( fgets ( buf, 1 << 10, fh ) ) { nrecords = nrecords + 1; char *pos = strchr(buf, ';'); *pos = 0x0; measurement = strtod ( pos + 1, NULL ); c = getcity ( buf, results, nresults ); if ( c < 0 ) { strcpy(results[nresults].city, buf); results[nresults].sum = measurement; results[nresults].max = measurement; results[nresults].min = measurement; results[nresults].count = 1; nresults++; } else { results[c].sum += measurement; results[c].count += 1; if ( measurement < results[c].min ) { results[c].min = measurement; } if (results[c].max < measurement) { results[c].max = measurement; } } } printf ( " Number of records read was %d\n", nrecords ); printf ( " Number of distinct cities encountered was %d\n", nresults ); qsort ( results, (size_t)nresults, sizeof(*results), cmp ); printf ( "\n" ); for ( i = 0; i < nresults; i++) { printf ( "%s=%.1f/%.1f/%.1f\n", results[i].city, results[i].min, results[i].sum / results[i].count, results[i].max ); } fclose ( fh ); tstop = clock ( ); printf ( "\n" ); printf ( " Run time was %f seconds.\n", ( double ) ( tstop - tstart ) / ( double ) CLOCKS_PER_SEC); /* Terminate. */ printf ( "\n" ); printf ( "1brc_naive():\n" ); printf ( " Normal end of execution.\n" ); timestamp ( ); return 0; } /******************************************************************************/ static int cmp ( const void *ptr_a, const void *ptr_b) /******************************************************************************/ /* Purpose: cmp() compares two city names for equality. Modified: 12 May 2024 Author: Original C version by Danny van Kooten. This version by John Burkardt. */ { return strcmp(((struct result *)ptr_a)->city, ((struct result *)ptr_b)->city); } /******************************************************************************/ static int getcity ( const char *city, struct result results[], int nresults ) /******************************************************************************/ /* Purpose: getcity() returns the index I of a given city in the list of cities. Modified: 12 May 2024 Author: Original C version by Danny van Kooten. This version by John Burkardt. */ { for ( int i = 0; i < nresults; i++ ) { if ( strcmp ( results[i].city, city ) == 0 ) { return i; } } return -1; } /******************************************************************************/ void timestamp ( ) /******************************************************************************/ /* Purpose: timestamp() prints the current YMDHMS date as a time stamp. Example: 17 June 2014 09:45:54 AM Licensing: This code is distributed under the MIT license. Modified: 01 May 2021 Author: John Burkardt */ { # define TIME_SIZE 40 static char time_buffer[TIME_SIZE]; const struct tm *tm; time_t now; now = time ( NULL ); tm = localtime ( &now ); strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm ); printf ( "%s\n", time_buffer ); return; # undef TIME_SIZE }