-
Notifications
You must be signed in to change notification settings - Fork 144
Size reductions #1783
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Size reductions #1783
Conversation
|
Hello @ccoffing, Nice work 4K byte savings on the distribution!! :) I am guessing that some of the literal string splits were designed for use with string merging at link time? Also, pretty tricky work on using a bit vector for testing for the C0 control codes. Fast, though initially hard to understand until I got it. Thanks for leaving in the switch statement as documentation. I found one line that might be in error, along with a couple other small comments posted separately for your comment. Thank you! |
elkscmd/ash/linenoise_elks.c
Outdated
| /* Cursor to left edge */ | ||
| strcpy(seq, "\r"); | ||
| abAppend(&ab,seq,strlen(seq)); | ||
| abAppend(&ab,"\r",2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be abAppend(...,1)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
elkscmd/cron/cron.c
Outdated
| printf(" "); | ||
| printtrig(&tabs[i].list[j].trigger); | ||
| printf("%s", tabs[i].list[j].command); | ||
| fputs(tabs[i].list[j].command, stdout); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure that replacing printf with fputs is actually smaller here? In the case where printf is already used, it seems this just drags in another function, rather than saving space as it would if printf could actually be replaced in full at link time. Same for a few other cases with printf->fputs substitution in this commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, changing back to printf saves 16 bytes on the binary. Done.
elkscmd/cron/crontab.c
Outdated
| seteuid(getuid()); | ||
| do { | ||
| fprintf(stderr, "Do you want to retry the same edit? "); | ||
| fputs("Do you want to retry the same edit? ", stderr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here as commented above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turns out that this doesn't matter (function and binary are same size either way) since something else is already pulling fputs in. In general, fputs should take fewer cycles when no formatting is required. But since I don't know how/why fputs is getting pulled in already (maybe it can be trimmed out...) I'll revert this for now.
| if (r == LINES - 1) | ||
| printf("\r"); | ||
| else printf("\n"); | ||
| putc(r == LINES - 1 ? '\r' : '\n', stdout); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to printf->fputs described above, doesn't this just drag in fputc, while also including printf? I would guess this results in large .o and final codefile ? (Same issue in tty-cp437.c).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think my initial motivation here was to save a few CPU cycles by avoiding the unnecessary format string parsing in vfprintf (which, when multiplied across screen redraws, might actually matter).
I just did a test:
Reverting cons.c and tty-cp437.c to printf as before, and doing a clean build:
$ du -b target/bin/
1337353 target/bin/
Clean build with cons.c and tty-cp437.c putc change as first presented here. Slightly trading space for time:
$ du -b target/bin/
1337369 target/bin/
Then converting cons.c and tty-cp437.c to fputs/putc (no printf), and doing a clean build:
$ du -b target/bin/
1337321 target/bin/
So it seems that avoiding printf where possible in tty code is a [tiny] win, whether the goal is to optimize for space or time.
Also unnecessary to clear errno when it is guaranteed to be set
- More precisely trim out DEBUG code - Combine similar strings - Use libc string functions not custom. Some would be omitted ifdef SYS5, but we don't define that for other reasons; just rely on __STDC__. - Reduce size of linenoise
Where possible, prefer setbuf over setvbuf (64 bytes smaller) or skip explicitly setting to fully buffered when it isn't necessary. It's redundant to fflush stdout,stderr before exit because stdio already registers its own atexit to fflush stdout and stderr.
|
After looking a bit more closely at However - some executables are linked with $(TINYPRINTF) (elkscmd/lib/tiny_printf.c). In those cases, beware of the substitutions used above because tiny_printf.c only defines a smaller/fast Thank you! |
So regarding TINYPRINTF, it's possible with my changes that some binaries went up in size and some went down (but on average a win). I'll keep that in mind. Thanks! |
Technically possible, but I don't think any of the programs you changed link with TINYPRINTF. In general, only very small programs that would otherwise use TINYPRINTF is definitely not compatible with anything that calls |
This is a grab-bag of little optimizations that have accumulated. It's only a few bytes and few cycles saved here and there, but I'm tired of sitting on them, and combined they cut 4k off the 2.8M media.
I think most of these changes stand on their own merits. But a few like to
lswere specifically sought out to bring the binary down to the next smaller filesystem block size.