1 /* This is part of the netCDF package. Copyright 2018 University
2 Corporation for Atmospheric Research/Unidata See COPYRIGHT file for
3 conditions of use. See www.unidata.ucar.edu for more info.
4
5 This program benchmarks creating a netCDF file with many objects.
6
7 Ed Hartnett
8 */
9
10 #include <config.h>
11 #include <nc_tests.h>
12 #include "err_macros.h"
13 #include <netcdf.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <time.h>
17 #include <sys/time.h> /* Extra high precision time info. */
18
19 /* We will create this file. */
20 #define FILE_NAME "bm_many_objs.nc"
21
22 /* Prototype from tst_utils.c. */
23 int nc4_timeval_subtract(struct timeval *result, struct timeval *x,
24 struct timeval *y);
25
main(int argc,char ** argv)26 int main(int argc, char **argv)
27 {
28 struct timeval start_time, end_time, diff_time;
29 double sec;
30 int nitem = 10000; /* default number of objects of each type */
31 int i;
32 int ncid;
33 int data[] = {42};
34 int g, grp, numgrp;
35 char gname[16];
36 int v, var, numvar, vn, vleft, nvars;
37
38 if(argc > 2) { /* Usage */
39 printf("NetCDF performance test, writing many groups and variables.\n");
40 printf("Usage:\t%s [N]\n", argv[0]);
41 printf("\tN: number of objects\n");
42 return(0);
43 }
44 for(i = 1; i < argc; i++) {
45 nitem = atoi(argv[i]);
46 }
47
48 /* create new file */
49 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
50 if (gettimeofday(&start_time, NULL))
51 ERR;
52 /* create N groups, printing time after every 1000 */
53 numgrp = nitem;
54 for(g = 1; g < numgrp + 1; g++) {
55 sprintf(gname, "group%d", g);
56 if (nc_def_grp(ncid, gname, &grp)) ERR;
57 if (nc_def_var(grp, "var", NC_INT, 0, NULL, &var)) ERR;
58 if(nc_enddef (grp)) ERR;
59 if(nc_put_var(grp, var, data)) ERR;
60 if(g%1000 == 0) { /* only print every 1000th group name */
61 if (gettimeofday(&end_time, NULL)) ERR;
62 if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
63 sec = diff_time.tv_sec + 1.0e-6 * diff_time.tv_usec;
64 printf("%s\t%.3g sec\n", gname, sec);
65 }
66 }
67 nc_close(ncid);
68
69 /* create new file */
70 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
71 /* create N variables, printing time after every 1000.
72 * Put NC_MAX_VARS variables per group (even though netcdf4 non-classic
73 * format does not limit variable count), create the necessary number
74 * of groups to hold nitem variables. */
75 numvar = nitem;
76 v = 1;
77 numgrp = (numvar - 1) / NC_MAX_VARS + 1;
78 vleft = numvar - (NC_MAX_VARS * (numgrp - 1));
79 if (gettimeofday(&start_time, NULL))
80 ERR;
81
82 for(g = 1; g < numgrp + 1; g++) {
83 sprintf(gname, "group%d", g);
84 if (nc_def_grp(ncid, gname, &grp)) ERR;
85 nvars = g < numgrp ? NC_MAX_VARS : vleft; /* leftovers on last time through */
86 for(vn = 1; vn < nvars + 1; vn++) {
87 int var;
88 char vname[20];
89 sprintf(vname, "variable%d", v);
90 if(nc_def_var(grp, vname, NC_INT, 0, NULL, &var)) ERR;
91 if(nc_put_var(grp, var, data)) ERR;
92 if(v%1000 == 0) { /* only print every 1000th variable name */
93 if (gettimeofday(&end_time, NULL)) ERR;
94 if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
95 sec = diff_time.tv_sec + 1.0e-6 * diff_time.tv_usec;
96 printf("%s/%s\t%.3g sec\n", gname, vname, sec);
97 }
98 v++;
99 }
100 }
101 nc_close(ncid);
102 FINAL_RESULTS;
103 }
104