Re: Are frozen files really that hot?
Daniel Goldman <[email protected]> Mon, 07 Jul 2014 17:13:59 -0700
| Newsgroups | gmane.comp.gnu.m4.general |
|---|---|
| Message-ID | <[email protected]> |
Thanks for the thoughtful response. On 7/3/2014 4:24 PM, Eric Blake wrote: > Frozen file support was added before I ever started hacking on m4; I'm > not sure what benchmarks were used at the time (other than the autoconf > case, since autoconf relies on them), and I have not personally tried to > benchmark it. It doesn't necessarily mean no benchmarks exist, just > that I haven't found any; conversely, I haven't had any reason to worry > about it. The changelog first entry related to frozen files is 1994. And frozen files were apparently totally implemented at that point. That's a long history! It is still possible frozen files were a failed experiment, in the sense that the cost is greater than the benefit. There certainly is a long history. > > While I agree with your notion that there is little evidence of benefit, > I disagree with your claim of a significant burden. The code is there, > it is covered by the testsuite, and we haven't had to patch it in > several years (thus no one is reporting bugs against it). I do not > consider that to be a maintenance burden, but evidence of something that > does its job well, even if the job is not useful to many. > > As to the complexity claim, the code is fairly well segregated (see > src/freeze.c); the additional code base needed for frozen files does not > intrude into the speed or memory taken by the normal code that works > without frozen files (pretty much one if() statement at shutdown on > whether to dump to a file, to call into freeze.c; then on load time, > freeze.c does its thing and sets up the internal hash tables of known > macros, then returns control to the normal input engine). I don't see > the code base being slowed down, because we don't have to maintain any > extra state just because something is frozen. > I thought there would be a significant maintenance burden. But you would know best. Yes, freeze.c is small. But I imagined there must be more, perhaps a bunch of stuff in some header. I don't understand the big picture of how the m4 source code is organized (and am going to try figuring it out, am not asking for an explanation, don't want to waste your time). Bottom line: if you don't consider it a significant maintenance burden, then no reason to change. I'm pleading ignorance of the source code, so I can't have it both ways... > It may have been smaller than you liked, but it was definitely non-zero, > and not in the noise. 30% may not be much, but it's better than a LOT > of premature optimizations I've seen in my days that have a difference > of no more than 1%. I wasn't trying to be flippant, but actually glad > that you now have a benchmark for your use case, which shows an actual > gain (proof that the code is not complete dead weight, even if it didn't > do as much as you wanted). Yes, 30% is non-zero. To me not enough to justify using frozen files. But I would grant that it's a matter of personal preference. There is no hard rule how much speed-up justifies some change. 1/2 second vs 1 second is a lot different from 50 seconds vs 100 seconds. Perhaps m4 was a bottleneck decades ago, and with the huge speedup of hardware (and improvement of those macros you did), is much less so. In my usage, m4 is not a bottleneck so far. If there was going to be another benchmark, I think a synthetic one would be better. Replicable. It would not be that hard to build, given agreement about what macros to benchmark. A shell script would automatically create the m4 definition and input files, and then run m4 either with frozen or not frozen. I thought of carrying this out, but (1) I did not feel comfortable specifying which macros to benchmark, and (2) my real-world benchmark was of more practical use to me. > >> Maybe the historical reasons were bad reasons. Maybe they don't apply >> today. My guess is there were better ways to deal with those O(n^2) (and >> even O(n^3)) macro definitions. You say they are gone now, so apparently >> someone found a better way. > > I was one of the programmers that spent a lot of time on autoconf trying > to eradicate stupid O(n^2) algorithms and replace it with faster > iterations, and with some definite success (the time it took to run > autoconf on a complex program such as coreutils was cut in half. > Admittedly, the time to run autoconf on one developer's machine is in > the noise compared to the time spent on running configure on all the > users' machines in the collective scheme of things, but faster developer > turnaround time can get patches to the users faster, so every little bit > helps). However, while I know autoconf runs faster now than it did in > 2.59 days, I don't know how much of that speed is due to improvements in > m4 (such as using unlocked io), in frozen file handling, or in > improvements to management of configure.ac constructs (the part of the > processing done after frozen files were loaded) - only that I was > working on speedups on all three fronts at the same time several years ago. > Sounds complex and tedious, a lot of hard work. >> I'm sure someone was trying to do their best >> way back when. But it's possibly they messed up, that frozen files were >> a failed experiment. Programmers make bad design decisions all the time, >> and they can persist for many years. It's possible that happened here. > > They are not a failed experiment, because autoconf still uses them. You > don't have to use it, but that doesn't mean it failed. And back-compat > demands that we can't rip it out. For that matter, I worry that ripping > it out might have more negative consequences than positive. > By "failed experiment", I meant maybe the speedup was not enough to really justify the work, or maybe better way to get to result. But you are right, it works and is used so in that sense is not failed. Yes, "ripping it out" would have negative consequences. I just imagined it had a significant maintenance downside, did not know. >> What are the autoconf "quadratic algorithms" you are referring to? Are >> they still around? If so, maybe there is a better approach. I would >> suggest that if there is a composite macro that is more or less general, >> widely used, and computation intensive, that would be a good candidate >> to consider using a builtin, which could potentially be much faster, >> much better, and much easier to use. But that would require an openness >> to adding builtin macros. > > https://www.gnu.org/software/m4/manual/m4.html#Foreach documents a > foreach macro, which (modulo `' vs. [] quoting) was originally lifted > from autoconf 2.59. I'm not sure if autoconf actually used foreach when > defining other macros in the files it eventually froze, or if it was > more a matter of using foreach in the definition of macros that then > caused quadratic expansion time while processing the user's > configure.ac. And even if the algorithm was quadratic, if your list is > small enough you'll never notice the poor scaling. > > Meanwhile, > https://www.gnu.org/software/m4/manual/m4.html#Improved-foreach > documents the improved foreach definition that is no longer quadratic, > in part because of tricks I employed in getting rid of the quadratic > recursion in newer autoconf in the 2.63 days. > > Another thing that I know was computation intensive was use of regex; > autoconf 2.59 definitely had some places where it used a regular > expression in order to define a new macro based on substitution of > patterns of an existing macro, and did so in an inefficient manner. In > newer autoconf, I made it a point to use fewer regex, to defer > expressions unless they were needed; and I also improved m4 to cache > frequently used expressions (as compiling a regex was a noticeable > hotspot in performance testing). This is another case where frozen > files matter (loading a frozen file does not have to compile the regular > expression used to define a macro) but where the gap may be smaller (the > code uses fewer regex to begin with). *** Thanks for the details. I have a question: Was there ever a suggestion that foreach might be implemented as a builtin? When I mentioned "a composite macro that is more or less general, widely used, and computation intensive", I had something like foreach in mind. Is it possible that a foreach builtin macro could potentially be faster, better, and easier to use? The part about using regex to generate new macros has my head spinning. I never imagined doing anything like that. I'm not saying it's bad. It's just very surprising. Not expecting a comment back. >> >> You totally make my point when you say "I'm not sure if you will see >> better or worse numbers from autoconf". If it's not faster, there is NO >> point to use frozen files. Perhaps without intending to, you make my >> point that there is a possibility frozen files are not so hot. > > But until someone actually runs a benchmark to prove one way or the > other, the status quo seems to be just fine. Yes, the status quo is OK. My main point was to point out what I observed, and find out if any other existing benchmarks. > >> BTW, I'm sure you would not see "worse numbers". I am NOT suggesting >> that frozen files slow things down. :) > > But they might. It is a very real possibility that with modern > hardware, and with improvements made in both m4 and autoconf, that > autoconf could be changed to avoid frozen files with no loss or even a > potential gain in performance. But until someone posts hard numbers, we > can speculate all day, and it won't matter. > Probably, nobody is going to post hard numbers. As you say, the status quo works OK, so why change it? And everyone is busy. It takes some effort to do a benchmark correctly. The right time to do the benchmark was decades ago. Maybe they did. I'm sure they were doing their best. >> >>> They're not mandatory to use. But at this point, we can't rip it out of >>> m4 - there are users that depend on it. The code is designed to not >>> penalize people that aren't using it. >> >> I never suggested frozen files were mandatory to use, so I don't get >> your point. I am suggesting is they are mandatory to maintain. And my >> guess is they add significant complexity to the software (you would be >> best placed to comment on that). And as m4 development seems more or >> less stuck based on what I read, maybe it might be a good idea to >> strategize before adding some other "feature", and to figure out how to >> get m4 development unstuck. And again, sometimes "less is more". > > Okay, then it sounds like we are on the same page about leaving it alone. > >> > While we have prepared the code to deprecate some command line options > that aren't very consistent, we haven't had to deprecate any features. > I don't see that marking frozen files as deprecated would make any > difference. > I basically agree, given there is apparently not the maintenance burden that I imagined there would be. > > At this point, m4 is stable enough that patches speak louder than words. > While it can be quite powerful at what it does, there doesn't seem to > be many people flocking to use it. Whether that is because people don't > know about it, or because m4 only fits a niche market, it's hard to > justify adding features when there is already such a low volume of > contribution and a lack of free time on my part to write new patches. > I'd love to review patches from others - but such patches are rarely > submitted. > > I _do_ like suggestions for improvement, but with the limited time I > spend on m4, I like it more when those suggestions are accompanied by an > implementation that demonstrate the improvement rather than just > describing it in prose. > You have a good point about submitting patches for review. I had the (probably naive) idea it was better for the user (me) to make a suggestion, and the expert (you) to do the coding. I know talk is cheap, a lot easier than changing source code. On the other hand, systems analysis (which I hope I'm good at) is valuable, too. And a user, even if a good C programmer, is unlikely to have an adequate understanding of the intricacies of the m4 source code. I get not exactly of tidal wave of m4 users. When I said "echo chamber", I was trying to convey that maybe just a few listeners on this group, certainly very few posts, so maybe more or less talking to myself. :( It's understandable that a low activity software is a lower priority to improve. m4 seems very forbidding and obscure to new users. I speak from experience. I use other initially very confusing but ultimately very useful software tools (vi, sed, awk, etc.). But m4 always seemed even more obscure and remote, not something for a "regular user". Finally, after many years, I made the effort to learn m4. I've read the manual several times, done some experiments. I have found it quite useful. I've written over 50,000 (mostly simple) macros already, a kind of data dictionary, used to process a variety of files. And it's doing most of what I want. It's just I ran into a few (IMO) rough edges, and so I felt compelled to post, in case helpful at some point. Of course, frozen files are not a "rough edge", just didn't speed things up much, at least in this one real-world case. Thanks, Daniel