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