diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-04-02 15:18:26 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-04-02 15:18:26 +0200 |
commit | dd02a05e082b96d76707964179921107cd43cdd8 (patch) | |
tree | f698e072011a48f335b8fa30babdc8724bdee011 | |
parent | 9f2f96edfa7eddd8a77b76ccae7c2ed88348182e (diff) | |
download | busybox-w32-dd02a05e082b96d76707964179921107cd43cdd8.tar.gz busybox-w32-dd02a05e082b96d76707964179921107cd43cdd8.tar.bz2 busybox-w32-dd02a05e082b96d76707964179921107cd43cdd8.zip |
build system: finer-grained selection of search speedup table.
KNOWN_APPNAME_OFFSETS=8 versus KNOWN_APPNAME_OFFSETS=0:
function old new delta
find_applet_by_name 55 136 +81
applet_nameofs - 14 +14
run_applet_and_exit 757 758 +1
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | applets/applet_tables.c | 65 |
1 files changed, 33 insertions, 32 deletions
diff --git a/applets/applet_tables.c b/applets/applet_tables.c index 48544f08d..843f2ec08 100644 --- a/applets/applet_tables.c +++ b/applets/applet_tables.c | |||
@@ -58,41 +58,32 @@ static int str_isalnum_(const char *s) | |||
58 | return 1; | 58 | return 1; |
59 | } | 59 | } |
60 | 60 | ||
61 | // Before linear search, narrow it down by looking at N "equidistant" names: | ||
62 | // KNOWN_APPNAME_OFFSETS cycles code_size | ||
63 | // 0 9057 | ||
64 | // 2 4604 +32 | ||
65 | // 4 2407 +75 | ||
66 | // 8 1342 +98 | ||
67 | // 16 908 +130 | ||
68 | // 32 884 +194 | ||
69 | // With 8, applet_nameofs[] table has 7 elements. | ||
70 | #define KNOWN_APPNAME_OFFSETS 8 | ||
71 | |||
72 | int main(int argc, char **argv) | 61 | int main(int argc, char **argv) |
73 | { | 62 | { |
74 | int i, j; | 63 | int i, j; |
75 | int ofs, offset[KNOWN_APPNAME_OFFSETS], index[KNOWN_APPNAME_OFFSETS]; | ||
76 | // unsigned MAX_APPLET_NAME_LEN = 1; | ||
77 | 64 | ||
78 | qsort(applets, NUM_APPLETS, sizeof(applets[0]), cmp_name); | 65 | // In find_applet_by_name(), before linear search, narrow it down |
66 | // by looking at N "equidistant" names. With ~350 applets: | ||
67 | // KNOWN_APPNAME_OFFSETS cycles | ||
68 | // 0 9057 | ||
69 | // 2 4604 + ~100 bytes of code | ||
70 | // 4 2407 + 4 bytes | ||
71 | // 8 1342 + 8 bytes | ||
72 | // 16 908 + 16 bytes | ||
73 | // 32 884 + 32 bytes | ||
74 | // With 8, int16_t applet_nameofs[] table has 7 elements. | ||
75 | int KNOWN_APPNAME_OFFSETS = 8; | ||
76 | // With 128 applets we do two linear searches, with 1..7 strcmp's in the first one | ||
77 | // and 1..16 strcmp's in the second. With 256 apps, second search does 1..32 strcmp's. | ||
78 | if (NUM_APPLETS < 128) | ||
79 | KNOWN_APPNAME_OFFSETS = 4; | ||
80 | if (NUM_APPLETS < 32) | ||
81 | KNOWN_APPNAME_OFFSETS = 0; | ||
79 | 82 | ||
80 | for (i = 0; i < KNOWN_APPNAME_OFFSETS; i++) | 83 | qsort(applets, NUM_APPLETS, sizeof(applets[0]), cmp_name); |
81 | index[i] = i * NUM_APPLETS / KNOWN_APPNAME_OFFSETS; | ||
82 | 84 | ||
83 | ofs = 0; | ||
84 | for (i = 0; i < NUM_APPLETS; i++) { | ||
85 | for (j = 0; j < KNOWN_APPNAME_OFFSETS; j++) | ||
86 | if (i == index[j]) | ||
87 | offset[j] = ofs; | ||
88 | ofs += strlen(applets[i].name) + 1; | ||
89 | } | ||
90 | /* If the list of names is too long refuse to proceed */ | ||
91 | if (ofs > 0xffff) | ||
92 | return 1; | ||
93 | if (!argv[1]) | 85 | if (!argv[1]) |
94 | return 1; | 86 | return 1; |
95 | |||
96 | i = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0666); | 87 | i = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0666); |
97 | if (i < 0) | 88 | if (i < 0) |
98 | return 1; | 89 | return 1; |
@@ -108,16 +99,26 @@ int main(int argc, char **argv) | |||
108 | printf("#define SINGLE_APPLET_MAIN %s_main\n", applets[0].main); | 99 | printf("#define SINGLE_APPLET_MAIN %s_main\n", applets[0].main); |
109 | } | 100 | } |
110 | 101 | ||
111 | if (KNOWN_APPNAME_OFFSETS > 0 && NUM_APPLETS > 2*KNOWN_APPNAME_OFFSETS) { | 102 | printf("#define KNOWN_APPNAME_OFFSETS %u\n\n", KNOWN_APPNAME_OFFSETS); |
112 | printf("#define KNOWN_APPNAME_OFFSETS %u\n\n", KNOWN_APPNAME_OFFSETS); | 103 | if (KNOWN_APPNAME_OFFSETS > 0) { |
104 | int ofs, offset[KNOWN_APPNAME_OFFSETS], index[KNOWN_APPNAME_OFFSETS]; | ||
105 | for (i = 0; i < KNOWN_APPNAME_OFFSETS; i++) | ||
106 | index[i] = i * NUM_APPLETS / KNOWN_APPNAME_OFFSETS; | ||
107 | ofs = 0; | ||
108 | for (i = 0; i < NUM_APPLETS; i++) { | ||
109 | for (j = 0; j < KNOWN_APPNAME_OFFSETS; j++) | ||
110 | if (i == index[j]) | ||
111 | offset[j] = ofs; | ||
112 | ofs += strlen(applets[i].name) + 1; | ||
113 | } | ||
114 | /* If the list of names is too long refuse to proceed */ | ||
115 | if (ofs > 0xffff) | ||
116 | return 1; | ||
113 | printf("const uint16_t applet_nameofs[] ALIGN2 = {\n"); | 117 | printf("const uint16_t applet_nameofs[] ALIGN2 = {\n"); |
114 | for (i = 1; i < KNOWN_APPNAME_OFFSETS; i++) | 118 | for (i = 1; i < KNOWN_APPNAME_OFFSETS; i++) |
115 | printf("%d,\n", offset[i]); | 119 | printf("%d,\n", offset[i]); |
116 | printf("};\n\n"); | 120 | printf("};\n\n"); |
117 | } | 121 | } |
118 | else { | ||
119 | printf("#define KNOWN_APPNAME_OFFSETS 0\n\n"); | ||
120 | } | ||
121 | 122 | ||
122 | //printf("#ifndef SKIP_definitions\n"); | 123 | //printf("#ifndef SKIP_definitions\n"); |
123 | printf("const char applet_names[] ALIGN1 = \"\"\n"); | 124 | printf("const char applet_names[] ALIGN1 = \"\"\n"); |