@cryptotaxi247 / netdata-1 / commits / ff2b6a7ce

procfile optimizations to eliminate parser variables and memory lookups

Costa Tsaousis (ktsaou) committed Feb 18, 2018 at 01:39 UTC ff2b6a7ce583ed5b83c282e94c3f7aa6362ec92f
3 files changed +39 -41
configure.ac
+1
@@ -124,6 +124,7 @@ AC_ARG_ENABLE(
124 AX_GCC_FUNC_ATTRIBUTE([returns_nonnull])
125 AX_GCC_FUNC_ATTRIBUTE([malloc])
126 AX_GCC_FUNC_ATTRIBUTE([noreturn])
127 +AX_GCC_FUNC_ATTRIBUTE([noinline])
128 AX_GCC_FUNC_ATTRIBUTE([format])
129 AX_GCC_FUNC_ATTRIBUTE([warn_unused_result])
130
src/common.h
+6
@@ -159,6 +159,12 @@
159 #define NEVERNULL
160 #endif
161
162 +#ifdef HAVE_FUNC_ATTRIBUTE_NOINLINE
163 +#define NOINLINE __attribute__((noinline))
164 +#else
165 +#define NOINLINE
166 +#endif
167 +
168 #ifdef HAVE_FUNC_ATTRIBUTE_MALLOC
169 #define MALLOCLIKE __attribute__((malloc))
170 #else
src/procfile.c
+32 -41
@@ -39,24 +39,22 @@ char *procfile_filename(procfile *ff) {
39 // ----------------------------------------------------------------------------
40 // An array of words
41
42 -static inline pfwords *pfwords_add(pfwords *fw, char *str) NEVERNULL;
43 -static inline pfwords *pfwords_add(pfwords *fw, char *str) {
42 +static inline void pfwords_add(procfile *ff, char *str) {
43 // debug(D_PROCFILE, PF_PREFIX ": adding word No %d: '%s'", fw->len, str);
44
45 + pfwords *fw = ff->words;
46 if(unlikely(fw->len == fw->size)) {
47 // debug(D_PROCFILE, PF_PREFIX ": expanding words");
48
49 - fw = reallocz(fw, sizeof(pfwords) + (fw->size + PFWORDS_INCREASE_STEP) * sizeof(char *));
49 + ff->words = fw = reallocz(fw, sizeof(pfwords) + (fw->size + PFWORDS_INCREASE_STEP) * sizeof(char *));
50 fw->size += PFWORDS_INCREASE_STEP;
51 }
52
53 fw->words[fw->len++] = str;
54 -
55 - return fw;
54 }
55
58 -static inline pfwords *pfwords_new(void) NEVERNULL;
59 -static inline pfwords *pfwords_new(void) {
56 +NEVERNULL
57 +static pfwords *pfwords_new(void) {
58 // debug(D_PROCFILE, PF_PREFIX ": initializing words");
59
60 size_t size = (procfile_adaptive_initial_allocation) ? procfile_max_words : PFWORDS_INCREASE_STEP;
@@ -82,25 +80,27 @@ static inline void pfwords_free(pfwords *fw) {
80 // ----------------------------------------------------------------------------
81 // An array of lines
82
85 -static inline pflines *pflines_add(pflines *fl, size_t first_word) NEVERNULL;
86 -static inline pflines *pflines_add(pflines *fl, size_t first_word) {
83 +NEVERNULL NOINLINE
84 +static size_t *pflines_add(procfile *ff) {
85 // debug(D_PROCFILE, PF_PREFIX ": adding line %d at word %d", fl->len, first_word);
86
87 + pflines *fl = ff->lines;
88 if(unlikely(fl->len == fl->size)) {
89 // debug(D_PROCFILE, PF_PREFIX ": expanding lines");
90
92 - fl = reallocz(fl, sizeof(pflines) + (fl->size + PFLINES_INCREASE_STEP) * sizeof(ffline));
91 + ff->lines = fl = reallocz(fl, sizeof(pflines) + (fl->size + PFLINES_INCREASE_STEP) * sizeof(ffline));
92 fl->size += PFLINES_INCREASE_STEP;
93 }
94
96 - fl->lines[fl->len].words = 0;
97 - fl->lines[fl->len++].first = first_word;
95 + ffline *ffl = &fl->lines[fl->len++];
96 + ffl->words = 0;
97 + ffl->first = ff->words->len;
98
99 - return fl;
99 + return &ffl->words;
100 }
101
102 -static inline pflines *pflines_new(void) NEVERNULL;
103 -static inline pflines *pflines_new(void) {
102 +NEVERNULL
103 +static pflines *pflines_new(void) {
104 // debug(D_PROCFILE, PF_PREFIX ": initializing lines");
105
106 size_t size = (unlikely(procfile_adaptive_initial_allocation)) ? procfile_max_words : PFLINES_INCREASE_STEP;
@@ -139,30 +139,29 @@ void procfile_close(procfile *ff) {
139 freez(ff);
140 }
141
142 -static void _procfile_parser_add_word(procfile *ff, size_t line, char *begin, char *end) {
142 +NOINLINE NEVERNULL
143 +static char *procfile_parser_add_word(procfile *ff, char *begin, char *end, size_t *line_words) {
144 *end = '\0';
144 - ff->words = pfwords_add(ff->words, begin);
145 - ff->lines->lines[line].words++;
145 + pfwords_add(ff, begin);
146 + (*line_words)++;
147 + return end + 1;
148 }
149
150 +NOINLINE
151 static void procfile_parser(procfile *ff) {
152 // debug(D_PROCFILE, PF_PREFIX ": Parsing file '%s'", ff->filename);
153
154 char *s = ff->data // our current position
155 , *e = &ff->data[ff->len] // the terminating null
153 - , *t = ff->data; // the first character of a quoted or a parenthesized string
156 + , *t = ff->data; // the first character of a word (or quoted / parenthesized string)
157
158 // the look up array to find our type of character
159 PF_CHAR_TYPE *separators = ff->separators;
160
161 char quote = 0; // the quote character - only when in quoted string
162 + size_t opened = 0; // counts the number of open parenthesis
163
160 - size_t
161 - l = 0 // counts the number of lines we added
162 - , w = 0 // counts the number of words we added
163 - , opened = 0; // counts the number of open parenthesis
164 -
165 - ff->lines = pflines_add(ff->lines, w);
164 + size_t *line_words = pflines_add(ff);
165
166 while(s < e) {
167 PF_CHAR_TYPE ct = separators[(unsigned char)(*s)];
@@ -175,9 +174,7 @@ static void procfile_parser(procfile *ff) {
174 if(likely(!quote && !opened)) {
175 if (likely(s != t)) {
176 // ending separator
178 - _procfile_parser_add_word(ff, l, t, s);
179 - w++;
180 - t = ++s;
177 + s = t = procfile_parser_add_word(ff, t, s, line_words);
178 }
179 else {
180 // starting separator
@@ -192,14 +189,11 @@ static void procfile_parser(procfile *ff) {
189 }
190 else if(likely(ct == PF_CHAR_IS_NEWLINE)) {
191 // end of line
195 - _procfile_parser_add_word(ff, l, t, s);
196 - w++;
197 - t = ++s;
192 + s = t = procfile_parser_add_word(ff, t, s, line_words);
193
194 // debug(D_PROCFILE, PF_PREFIX ": ended line %d with %d words", l, ff->lines->lines[l].words);
195
201 - ff->lines = pflines_add(ff->lines, w);
202 - l++;
196 + line_words = pflines_add(ff);
197 }
198 else if(likely(ct == PF_CHAR_IS_QUOTE)) {
199 if(unlikely(!quote && s == t)) {
@@ -211,9 +205,7 @@ static void procfile_parser(procfile *ff) {
205 // quote closed
206 quote = 0;
207
214 - _procfile_parser_add_word(ff, l, t, s);
215 - w++;
216 - t = ++s;
208 + s = t = procfile_parser_add_word(ff, t, s, line_words);
209 }
210 else
211 s++;
@@ -235,9 +227,7 @@ static void procfile_parser(procfile *ff) {
227 opened--;
228
229 if(!opened) {
238 - _procfile_parser_add_word(ff, l, t, s);
239 - w++;
240 - t = ++s;
230 + s = t = procfile_parser_add_word(ff, t, s, line_words);
231 }
232 else
233 s++;
@@ -256,7 +246,7 @@ static void procfile_parser(procfile *ff) {
246 s = &ff->data[ff->size - 1];
247 }
248
259 - _procfile_parser_add_word(ff, l, t, s);
249 + procfile_parser_add_word(ff, t, s, line_words);
250 }
251 }
252
@@ -307,7 +297,8 @@ procfile *procfile_readall(procfile *ff) {
297 return ff;
298 }
299
310 -static inline void procfile_set_separators(procfile *ff, const char *separators) {
300 +NOINLINE
301 +static void procfile_set_separators(procfile *ff, const char *separators) {
302 static PF_CHAR_TYPE def[256];
303 static char initilized = 0;
304