Go Down

Topic: Performance enhancements to Print.cpp (Read 182 times) previous topic - next topic


I have three suggestions here. The first one is a no-brainer I think. The others -- not sure if you'd be interested.

1) In Print::printFloat() a simple change will make it run faster. In the loop where you are computing the rounding offset, change this:

Code: [Select]
for (uint8_t i=0; i<digits; ++i) rounding /= 10.0;

to this:

Code: [Select]
for (uint8_t i=0; i<digits; ++i) rounding *= 0.10;

I checked the assembly output, and the compiler will not optimize the divide by 10 into a multiply by 0.1 -- probably that's on purpose. The first technique does a floating divide which (I believe) is slower than a multiply. While this is perhaps not a huge savings...it really does cost nothing AFAICT.

The next two are in Print::printNumber()

BTW, I notice someone already found the optimization trick of using divide and mod together in there. h/t to whoever found that one!

One thing you could do there is a code space/speed tradeoff. You might or might not be interested:

If the base argument is a power of two, the output can be generated with simple binary AND and shift instructions instead of having to repeatedly divide by the base. You would have to add a test for a binary base and a separate block of code to do the mask/shift operations. My guess is that it would cost about 100 bytes of code space. Perhaps that's too much to make it interesting. Maybe this has already been discussed?

Finally, a range-checking question/suggestion -- there is no test for a ridiculously large base argument value ... e.g. someone could pass in 255 for the base. Doing that doesn't really hurt anything per se but there will of course be gibberish output. Not sure if anyone has any use for base > 16...so it could be limited there. OTOH, if code bytes are king, then I would understand why you'd leave that out. I suspect this may have already been discussed at length in the past...just ignore it if that's the case.

Go Up