nano-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Nano-devel] [PATCH] Optimize the order of struct members


From: Devin Hussey
Subject: [Nano-devel] [PATCH] Optimize the order of struct members
Date: Tue, 21 Aug 2018 19:46:42 -0400

I meant to submit this a while ago, it had been bugging me.

Just a minor tweak to optimize memory usage and list performance.

Forgot to put it in the message, but I changed parse_colors to be a static function, because it isn't used anywhere else.
----------------
From e1da232d721c1a228f5bfdcae94ef80b88fa0364 Mon Sep 17 00:00:00 2001
From: Devin Hussey <address@hidden>
Date: Tue, 21 Aug 2018 18:43:57 -0400
Subject: [PATCH] Optimize the order of struct members

- Reorder members to reduce padding and wasted RAM, most noticeable on x64
- Put links first so foo->next is a simple dereference
- Shrink pairnum to a short (ncurses uses a short for this as well)
- Replace rex_flags with a bool called ignore_case. This prevents using an
  entire word boundary in x64.
- long is an unreliable type, replace it with int.

Signed-off-by: Devin Hussey <address@hidden>
---
 src/color.c  |   5 ++-
 src/nano.h   | 125 ++++++++++++++++++++++++++-------------------------
 src/rcfile.c |  12 ++---
 3 files changed, 73 insertions(+), 69 deletions(-)

diff --git a/src/color.c b/src/color.c
index 036b4d45..c56d4d7a 100644
--- a/src/color.c
+++ b/src/color.c
@@ -272,14 +272,15 @@ void color_update(void)
  /* If a syntax was found, compile its specified regexes (which have
  * already been checked for validity when they were read in). */
  for (ink = openfile->colorstrings; ink != NULL; ink = ink->next) {
+ int rex_flags = NANO_REG_EXTENDED | ((ink->ignore_case) ? REG_ICASE : 0);
  if (ink->start == NULL) {
  ink->start = (regex_t *)nmalloc(sizeof(regex_t));
- regcomp(ink->start, fixbounds(ink->start_regex), ink->rex_flags);
+ regcomp(ink->start, fixbounds(ink->start_regex), rex_flags);
  }
 
  if (ink->end_regex != NULL && ink->end == NULL) {
  ink->end = (regex_t *)nmalloc(sizeof(regex_t));
- regcomp(ink->end, fixbounds(ink->end_regex), ink->rex_flags);
+ regcomp(ink->end, fixbounds(ink->end_regex), rex_flags);
  }
  }
 }
diff --git a/src/nano.h b/src/nano.h
index c0779801..8c51234b 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -184,19 +184,8 @@ typedef enum {
 /* Structure types. */
 #ifdef ENABLE_COLOR
 typedef struct colortype {
- short fg;
- /* This syntax's foreground color. */
- short bg;
- /* This syntax's background color. */
- bool bright;
- /* Is this color A_BOLD? */
- int pairnum;
- /* The color pair number used for this foreground color and
- * background color. */
- int attributes;
- /* Pair number and brightness composed into ready-to-use attributes. */
- int rex_flags;
- /* The regex compilation flags (with or without REG_ICASE). */
+ struct colortype *next;
+ /* Next set of colors. */
  char *start_regex;
  /* The start (or all) of the regex string. */
  regex_t *start;
@@ -205,20 +194,33 @@ typedef struct colortype {
  /* The end (if any) of the regex string. */
  regex_t *end;
  /* The compiled end (if any) of the regex string. */
- struct colortype *next;
- /* Next set of colors. */
  int id;
  /* Basic id for assigning to lines later. */
+ int attributes;
+ /* Pair number and brightness composed into ready-to-use attributes. */
+ short fg;
+ /* This syntax's foreground color. */
+ short bg;
+ /* This syntax's background color. */
+ short pairnum;
+ /* The color pair number used for this foreground color and
+ * background color. */
+ bool ignore_case;
+ /* Whether this ignores case. */
+ bool bright;
+ /* Whether this is A_BOLD. */
 } colortype;
 
 typedef struct regexlisttype {
- char *full_regex;
- /* A regex string to match things that imply a certain syntax. */
  struct regexlisttype *next;
  /* The next regex. */
+ char *full_regex;
+ /* A regex string to match things that imply a certain syntax. */
 } regexlisttype;
 
 typedef struct syntaxtype {
+ struct syntaxtype *next;
+ /* Next syntax. */
  char *name;
  /* The name of this syntax. */
  regexlisttype *extensions;
@@ -237,11 +239,13 @@ typedef struct syntaxtype {
  /* The colors and their regexes used in this syntax. */
  int nmultis;
  /* How many multiline regex strings this syntax has. */
- struct syntaxtype *next;
- /* Next syntax. */
 } syntaxtype;
 
 typedef struct lintstruct {
+ struct lintstruct *next;
+ /* Next error. */
+ struct lintstruct *prev;
+ /* Previous error. */
  ssize_t lineno;
  /* Line number of the error. */
  ssize_t colno;
@@ -250,10 +254,6 @@ typedef struct lintstruct {
  /* Error message text. */
  char *filename;
  /* Filename. */
- struct lintstruct *next;
- /* Next error. */
- struct lintstruct *prev;
- /* Previous error. */
 } lintstruct;
 
 /* Flags that indicate how a multiline regex applies to a line. */
@@ -273,14 +273,14 @@ typedef struct lintstruct {
 
 /* More structure types. */
 typedef struct filestruct {
- char *data;
- /* The text of this line. */
- ssize_t lineno;
- /* The number of this line. */
  struct filestruct *next;
  /* Next node. */
  struct filestruct *prev;
  /* Previous node. */
+ char *data;
+ /* The text of this line. */
+ ssize_t lineno;
+ /* The number of this line. */
 #ifdef ENABLE_COLOR
  short *multidata;
  /* Array of which multi-line regexes apply to this line. */
@@ -307,19 +307,25 @@ typedef struct partition {
 
 #ifndef NANO_TINY
 typedef struct undo_group {
+ struct undo_group *next;
  ssize_t top_line;
  /* First line of group. */
  ssize_t bottom_line;
  /* Last line of group. */
  char **indentations;
  /* String data used to restore the affected lines; one per line. */
- struct undo_group *next;
 } undo_group;
 
 typedef struct undo {
+ struct undo *next;
+ /* A pointer to the undo item of the preceding action. */
  ssize_t lineno;
+
  undo_type type;
  /* What type of undo this was. */
+ int xflags;
+ /* Some flag data we need. */
+
  size_t begin;
  /* Where did this action begin or end. */
  char *strdata;
@@ -328,8 +334,6 @@ typedef struct undo {
  /* The file size before the action. */
  size_t newsize;
  /* The file size after the action. */
- int xflags;
- /* Some flag data we need. */
  undo_group *grouping;
  /* Undo info specific to groups of lines. */
 
@@ -342,24 +346,29 @@ typedef struct undo {
  /* Mostly the line number of the current line; sometimes something else. */
  size_t mark_begin_x;
  /* The x position corresponding to the above line number. */
- struct undo *next;
- /* A pointer to the undo item of the preceding action. */
+
 } undo;
 #endif /* !NANO_TINY */
 
 #ifdef ENABLE_HISTORIES
 typedef struct poshiststruct {
+ struct poshiststruct *next;
  char *filename;
  /* The file. */
  ssize_t lineno;
  /* Line number we left off on. */
  ssize_t xno;
  /* x position in the file we left off on. */
- struct poshiststruct *next;
 } poshiststruct;
 #endif
 
 typedef struct openfilestruct {
+#ifdef ENABLE_MULTIBUFFER
+ struct openfilestruct *next;
+ /* The next open file, if any. */
+ struct openfilestruct *prev;
+ /* The preceding open file, if any. */
+#endif
  char *filename;
  /* The file's name. */
  filestruct *fileage;
@@ -381,19 +390,19 @@ typedef struct openfilestruct {
  /* The file's x position we would like. */
  ssize_t current_y;
  /* The file's y-coordinate position. */
- bool modified;
- /* Whether the file has been modified. */
  struct stat *current_stat;
  /* The file's current stat information. */
+#ifdef ENABLE_COLOR
+ syntaxtype *syntax;
+ /* The  syntax struct for this file, if any. */
+ colortype *colorstrings;
+ /* The file's associated colors. */
+#endif
 #ifndef NANO_TINY
  filestruct *mark;
  /* The line in the file where the mark is set; NULL if not set. */
  size_t mark_x;
  /* The mark's x position in the above line. */
- mark_type kind_of_mark;
- /* Whether it is a soft (with Shift) or a hard mark. */
- file_format fmt;
- /* The file's format -- Unix or DOS or Mac or mixed. */
  undo *undotop;
  /* The top of the undo list. */
  undo *current_undo;
@@ -404,35 +413,29 @@ typedef struct openfilestruct {
  /* The type of the last action the user performed. */
  char *lock_filename;
  /* The path of the lockfile, if we created one. */
+ mark_type kind_of_mark;
+ /* Whether it is a soft (with Shift) or a hard mark. */
+ file_format fmt;
+ /* The file's format -- Unix or DOS or Mac or mixed. */
 #endif
-#ifdef ENABLE_COLOR
- syntaxtype *syntax;
- /* The  syntax struct for this file, if any. */
- colortype *colorstrings;
- /* The file's associated colors. */
-#endif
-#ifdef ENABLE_MULTIBUFFER
- struct openfilestruct *next;
- /* The next open file, if any. */
- struct openfilestruct *prev;
- /* The preceding open file, if any. */
-#endif
+ bool modified;
+ /* Whether the file has been modified. */
 } openfilestruct;
 
 #ifdef ENABLE_NANORC
 typedef struct rcoption {
  const char *name;
  /* The name of the rcfile option. */
- long flag;
+ int flag;
  /* The flag associated with it, if any. */
 } rcoption;
 #endif
 
 typedef struct sc {
+ struct sc *next;
+ /* Next in the list. */
  const char *keystr;
  /* The string that describes a keystroke, like "^C" or "M-R". */
- bool meta;
- /* Whether this is a Meta keystroke. */
  int keycode;
  /* The integer that, together with meta, identifies the keystroke. */
  int menus;
@@ -450,15 +453,19 @@ typedef struct sc {
  char *expansion;
  /* The string of keycodes to which this shortcut is expanded. */
 #endif
- struct sc *next;
- /* Next in the list. */
+ bool meta;
+ /* Whether this is a Meta keystroke. */
 } sc;
 
 typedef struct subnfunc {
+ struct subnfunc *next;
+ /* Next item in the list. */
  void (*func)(void);
  /* The actual function to call. */
  int menus;
  /* In what menus this function applies. */
+ int toggle;
+ /* If this is a toggle, which toggle to affect. */
  const char *desc;
  /* The function's short description, for example "Where Is". */
 #ifdef ENABLE_HELP
@@ -470,16 +477,12 @@ typedef struct subnfunc {
 #endif
  bool viewok;
  /* Is this function allowed when in view mode? */
- long toggle;
- /* If this is a toggle, which toggle to affect. */
- struct subnfunc *next;
- /* Next item in the list. */
 } subnfunc;
 
 #ifdef ENABLE_WORDCOMPLETION
 typedef struct completion_word {
- char *word;
  struct completion_word *next;
+ char *word;
 } completion_word;
 #endif
 
diff --git a/src/rcfile.c b/src/rcfile.c
index 08de4d67..98d0723e 100644
--- a/src/rcfile.c
+++ b/src/rcfile.c
@@ -629,13 +629,13 @@ bool parse_color_names(char *combostr, short *fg, short *bg, bool *bright)
 }
 
 /* Parse the color string in the line at ptr, and add it to the current
- * file's associated colors.  rex_flags are the regex compilation flags
- * to use, excluding or including REG_ICASE for case (in)sensitivity. */
-void parse_colors(char *ptr, int rex_flags)
+ * file's associated colors. */
+static void parse_colors(char *ptr, bool ignore_case)
 {
  short fg, bg;
  bool bright;
  char *item;
+ int rex_flags = NANO_REG_EXTENDED | ((ignore_case) ? REG_ICASE : 0);
 
  if (!opensyntax) {
  rcfile_error(N_("A '%s' command requires a preceding 'syntax' command"),
@@ -698,7 +698,7 @@ void parse_colors(char *ptr, int rex_flags)
  newcolor->fg = fg;
  newcolor->bg = bg;
  newcolor->bright = bright;
- newcolor->rex_flags = rex_flags;
+ newcolor->ignore_case = ignore_case;
 
  newcolor->start_regex = mallocstrcpy(NULL, item);
  newcolor->start = NULL;
@@ -980,9 +980,9 @@ void parse_rcfile(FILE *rcstream, bool syntax_only)
  ;
 #endif
  else if (strcasecmp(keyword, "color") == 0)
- parse_colors(ptr, NANO_REG_EXTENDED);
+ parse_colors(ptr, FALSE);
  else if (strcasecmp(keyword, "icolor") == 0)
- parse_colors(ptr, NANO_REG_EXTENDED | REG_ICASE);
+ parse_colors(ptr, TRUE);
  else if (strcasecmp(keyword, "linter") == 0)
  pick_up_name("linter", ptr, &live_syntax->linter);
  else if (syntax_only && (strcasecmp(keyword, "set") == 0 ||
-- 
2.18.0

reply via email to

[Prev in Thread] Current Thread [Next in Thread]