Post by Denis VlasenkoPost by Rob LandleyPost by Denis VlasenkoExamples of things which should care about it
od, seq, uniq -c, tcpdump, hexdump...
How many of these users actually need a malloc, and how many is it
essentially a better sprintf?
The attached test program shows that snprintf is 2.5 times slower
sprintf='12345678' count=27346
utoa_to_buf='12345678' count=69880
utoa='12345678' count=65934
A few days ago I ran "hexdump | grep" over entire hard drive.
Took a long time. I wish hexdump was optimized a bit better...
I haven't really looked closely at hexdump, but what does a base 10 utoa have
to do with a base 16 hexdump?
Post by Denis VlasenkoPost by Rob LandleyPost by Denis VlasenkoPost by Rob LandleyPost by Denis Vlasenkogcc optimizes it out to simple 1000000000 constant
(if sizeof(unsigned)==4, that is).
When is sizeof(unsigned) not going to be 4 on any Linux platform? We
use the lp64 model (as do all modern Unix variants, including MacOS
X), where only long and pointer are 64 bit.
http://www.unix.org/whitepapers/64bit.html
What about Alpha? I heard that it has (had?) sizeof(int)==8.
A) Not on Linux. Linux standardized on LP64.
I am not sure. It looks like you are not sure too.
Apparently I didn't make myself clear.
Linux standardized on LP64, following the official Open Group recommendations
for all Unix platforms. I am sure of this, and there were good reasons for
it. The research behind the decision is stated here:
http://www.unix.org/version2/whatsnew/lp64_wp.html
I believe all 64-bit Linux platforms are x86-64. x86-64 is LP64. PPC 64 is
LP64. Even Itanic is LP64. Because there's a _spec_ that says LP64 and the
Linux developers have announced support for that spec. It seems highly
unlikely for the Alpha port to not be LP64, but it's hard looking up
information on the alpha because the platform's so obsolete. (The Alpha
Linux FAQ was last updated six years ago.)
However, google for "linux alpha sizeof int" and the first hit is the Wine
developers talking about it (three years ago), where they point out that
sizeof(int) != sizeof(void *), because Alpha Linux is LP64.
Here's explicitly running a program on Alpha to print out sizeof(int) and
sizeof(long):
http://www.alphalinux.org/archives/axp-list/January2001/0072.shtml
Post by Denis VlasenkoPost by Rob LandleyB) If it's that broken, I don't care.
What's broken about it? If the CPU is _designed_ to handle
mostly 64-bit operands, then it's only natural to make
"int" type 64-bit.
No, it's natural to make "long" 64 bit, "int" 32 bit, "short" 16 bit,
and "char" 8 bit.
If Alpha was broken that way, I would just document that BusyBox does not
support it. I see no reason to add support for something that's _both_
stupid and obsolete.
Post by Denis VlasenkoIIRC Alpha took a simpler "we are a fully 64 animal"
route.
I.E. we don't handle 32, 16, or 8 bit data types well.
Post by Denis VlasenkoSane C ABI on such CPU should use 64-bit ints,
or else you will drown in zillions of "n &= 0x00000000fffffffff"
type instructions which will enforce 32-bitness
on 64-bit CPU.
This is sad, but the deficiencies of Alpha's instruction set really are not
BusyBox's problem. Should we have a 64 bit char type for similar reasons?
Post by Denis VlasenkoI think I'm starting to waste your (and my) time.
Alpha is almost history now...
Bernhard's still adding Tru64 support. It's his pet platform...
Post by Denis VlasenkoPost by Rob LandleyPost by Denis VlasenkoPost by Rob LandleyPost by Denis VlasenkoSo, do you want me to
a) remove #ifdef NOT_NEEDED_YET part
or
b) enable it and use it in ash?
The first, please.
A general rule of thumb: we can always add code to the tree later.
(And if we remove it, we can always add it _back_ later.)
See attached patch.
Well, it's definitely an improvement. However, it would be nice if you
could call itoa on a buffer and have it actually fill in that buffer from
the start, so you could use it like you could sprintf or strcpy, and not
potentially have to track two pointers to your own buffer.
That will need either a clever method to determine how much digits are
there _before_ we do the conversion, or copying the result.
Nope. See the checkin I did for libbb/xfuncs.c. Yes, it potentially does a
few extra divides, but it still does 1.4 million utoa_to_buf() per second on
my laptop.
Post by Denis VlasenkoI hope that in most cases you can just
do_something(utoa_to_buf(n, buf, sizeof(buf));
(Actually, im most cases people will just use do_something(utoa(n)); ...)
Yup. It's not returning the buf from utoa_to_buf(). It can if there's a
pressing need, but utoa() and itoa() both return it and that's probably the
common case for inline use.
Post by Denis VlasenkoPost by Rob LandleyI did a quick stab at that and checked it into xfuncs.c, and now I'm
about to pass out. Could you tell me if that's useful, or if not what
did I screw up? I have to go fall over and pass out now, it's 4 am and I
have work in the morning...
Aha! So you DO have a clever method! :) Thanks!
Hmmm.... (/me takes a look) I think I can improve on that.
Glances at attachment... You spotted my lack of bounds checking, which is
definitely a big oversight on my part. :)
Post by Denis VlasenkoPlease see (and run) attached program. utoa_to_buf_rob is your version
copied from xfuncs.c. Two problems: it's almost as slow as sprintf
and it doesn't check for buflen. utoa_to_buf_rob2 is a speed improved
version and utoa_to_buf_rob2_with_check adds compile-time check
that unsigned is really 32-bit and also correctly handles buflen.
On even the 64-bit platforms BusyBox targets, unsigned is 32 bit. I'm pretty
sure of this one.
The lookup table is a classic size/speed tradeoff, something BusyBox has
traditionally come down on the "size" side of. Doing a write() on the result
is going to be way slower than the actual conversion anyway. What actual
bottleneck are you seeing?
I definitely agree the bounds checking needs to be added, though. I'll do
that now...
Rob
--
Never bet against the cheap plastic solution.