Re: itoa replacement ALMOST perfect
In Assign(my Itoa function) I changed this:
Assign(buf, bits);
to
*this= buf;
as a test for you.
And it made my function 1 second slower; bringing it to 4.5 seconds. Not even close to 10.
And I did give you more than enouph code to compile this and test it yourselves. You can easily take that function and return a string. It will require almost no effort.
Re: itoa replacement ALMOST perfect
Quote:
Originally Posted by aewarnick
And I did give you more than enouph code to compile this and test it yourselves.
You must provide *your* code in a compilable form that we can just copy and paste it in our compiler and test. We still do not know what aStr is. Once we have to guess, make up things, or fill in the gaps with our own code, then the tests become biased and invalid.
Quote:
It will require almost no effort.
It should require *no* effort from us, except using the copy and paste function and push the compile button.
Regards,
Paul McKenzie
Re: itoa replacement ALMOST perfect
Quote:
Originally Posted by aewarnick
In Assign(my Itoa function) I changed this:
Assign(buf, bits);
to
*this= buf;
as a test for you.
And it made my function 1 second slower; bringing it to 4.5 seconds. Not even close to 10.
You also didn't mention whether you compiled this as a release with optimizations turned on or whether you are timing a debug version.
We are trying to believe you, but this sort of dramatic speed increase given that your function is a *full* version of the standard function is very uncommon. It is usually only accomplished by very experienced programmers, and usually only those that are familiar with the code already to know what exactly is slow.
It is not done by persons who happen to put a function together in less than a few hours and "lo and behold", the function is 3 times faster than the standard function. That is just too hard to believe at this point.
If it is the case that you have a function 3 times faster than itoa(), report this to PJ Plauger at DinkumWare, since he is the one that wrote the standard library for Visual C++.
So the real question is this: what makes itoa() slow, if it is slow?
Regards,
Paul McKenzie
Re: itoa replacement ALMOST perfect
I whipped it up real quick. So there may be mistakes. But IntToStr seems to be faster most of the time even if radix is 10.
http://foryouandi.com/Programs/index.php
And I did say I build it in Release with /O2 optimizations in the other thread.
Re: itoa replacement ALMOST perfect
Compiled on Visual C++ 6.0 (Maximize Speed). I replaced "int64" with just plain old "int".
Quote:
loops = 10000
itoa 0
-2147483648
IntToStr 0
-2147483648
loops = 100000
itoa 0.032
-2147483648
IntToStr 0.031
-2147483648
loops = 1000000
itoa 0.312
-2147483648
IntToStr 0.25
-2147483648
So far there is an increase, but not three-fold.
Changing your Test() function to the following:
Code:
void Test()
{
int b=0;
uint radix=10;
string s;
s.resize(65);
const uint bits= sizeof(b)*CHAR_BIT;
char c[bits+1];
uint i;
ResetAndStartTimer("itoa");
for(i= 0; i<loops; ++i)
{
for ( int j = 0; j < 10000; ++j )
s = itoa(j, c, radix);
}
StopAndLog();
cout << s <<"\n"<<endl;
ResetAndStartTimer("IntToStr");
for(i= 0; i<loops; ++i)
{
for ( int j = 0; j < 10000; ++j )
s = IntToStr(j, c, radix);
}
StopAndLog();
cout << s <<"\n"<<endl;
testInt += b*b*b+30*b/6;
}
Quote:
loops = 10000
itoa 18.14
9999
IntToStr 15.657
9999
Again not a three fold increase in speed.
The other check which was not made is to see if the answers are correct. You should write the code to verify that your IntToStr() function actually does work by comparing the return result with itoa() with more than one number.
Regards,
Paul McKenzie
Re: itoa replacement ALMOST perfect
I did say that with a radix of 2 mine is much much faster. Try it, you'll see.
Re: itoa replacement ALMOST perfect
Quote:
Originally Posted by aewarnick
I did say that with a radix of 2 mine is much much faster. Try it, you'll see.
The code you have shows a radix of 10, so this is what I tried. However, this brings me back to my point of writing tests that are biased.
Sure, you can take practically any standard function (or class) and write your own version that is optimized for only certain data or conditions. This does not count as a "faster replacement", since it is only fast for one or just a few conditions.
This reminds me --
I remember someone claiming they had a string class faster than std::string, and they only tested it against concatenation of single characters to the string in a loop. The tests that this person wrote were delibrately written to take advantage of the single char concatentation. Yes, the home-made string class was faster when it came to concatenating single characters onto a string, but when the code was tested under general conditions (meaning the test was then written by another party) and with real-life examples, it was a failure and proved to be much slower than std::string.
I did what any other person who really wanted to use your code would do -- and that is to test against all and/or any criteria, and not test it against something that you know it is optimized for. The function takes a radix value, so it is only reasonable to test against different radix values, not just 2.
Regards,
Paul McKenzie
Re: itoa replacement ALMOST perfect
I agree. For that very same reason, I set b to int_min because the test is just unfair for me otherwise if radix is 2. I wanted all bits output all the time in binary mode, unlike what itoa does:
int 1;
itoa would output 1.
mine would output 31 zeros, then a 1.
Besides, we have both verified that IntToStr is faster dealing with a radix of 10 and 2 than itoa is.
One thing I did not even try to test was a radix of 16. Don't be surprised if it doesn't work right.
Re: itoa replacement ALMOST perfect
http://foryouandi.com/Programs/index.php
Now works perfectly for hex (radix==16) and seems to be just as fast as before. I also changed BOOL to bool. I was under the impression that BOOL was faster but my tests showed it was not. What do you think?
Paul, that is a good idea about checking to see if my function is always outputting correctly. I'll do that tonight and post back...if my wife lets me.
Re: itoa replacement ALMOST perfect
Quote:
Originally Posted by aewarnick
One thing I did not even try to test was a radix of 16. Don't be surprised if it doesn't work right.
Remember, this is only for one compiler. I have not tested this under any other version of Visual C++, or some other compiler.
All of this depends on how itoa() is implemented for a certain compiler. There is no guideline on how fast or slow this function is supposed to perform or how it is to be implemented. Another compiler vendor may have written itoa() all or most of it in assembly langage (and many C run-time functions are done this way).
Therefore be prepared for varying successes and failures when you run your code on another compiler.
Regards,
Paul McKenzie
Re: itoa replacement ALMOST perfect
Quote:
Originally Posted by aewarnick
http://foryouandi.com/Programs/index.php
Now works perfectly for hex (radix==16) and seems to be just as fast as before. I also changed BOOL to bool. I was under the impression that BOOL was faster but my tests showed it was not. What do you think?
A bool is an actual C++ type. A BOOL is a macro, and assuming it is defined in windows.h, it is nothing more than an int. Therefore if you want your code to be portable to other compilers, use bool.
Quote:
Paul, that is a good idea about checking to see if my function is always outputting correctly. I'll do that tonight and post back...if my wife lets me.
If any step can bring the whole thing down like a house of cards, it's this one, and that is testing to see if the output is correct.
Regards,
Paul McKenzie
Re: itoa replacement ALMOST perfect
That intToStr is faster in the profile test could come about simply because the compiler is able to optimise the call of a local function more than one through a library. It may even be inlining it.
Put intToStr in a DLL and call it that way for a fairer test.
Re: itoa replacement ALMOST perfect
Can't you just look at the assembly output? And is it common that dll functions are slower because they're in a dll?
I thought I would keep everyone updated as to where i'm at. I am testing my IntToStr function and comparing the output with itoa's output. So far, with a radix of 10 and 16 everything is the same. I had this running all night. My first test is from 1 to int_max. My second test will be the same except from int_min.
For the first test, again, has been running ALL NIGHT! I didn't realize how big int_max was. I'm currently around:
50000000
int_max is around:
2000000000
How big is 2000000000 anyway? Is that 2 gig?
Re: itoa replacement ALMOST perfect
Quote:
Originally Posted by aewarnick
Can't you just look at the assembly output? And is it common that dll functions are slower because they're in a dll?
Yes, it will be slower. The compiler can optimize the code globally, i.e. may make the function inline.
For the DLL function, there is no way the compiler can inline this function, since there is no way for it to optimize calling it (it's already compiled, and in an external module). So basically the compiler has to go with the "push arguments" and "call" set of operations when calling the DLL function, while your function benefited from the compiler's optimizer, eliminating these steps.
As a matter of fact, I did look at the assembly output. Your function generated no calls to "push arguments" and then "call", while the DLL function call must do this.
So NMTop40 is correct. Place your version of itoa() in a DLL, and then test. Then there is no optimization or any other things that the compiler may do to take advantage of code that is written inline.
Regards,
Paul McKenzie
Re: itoa replacement ALMOST perfect
I didn't make the dll yet, however, I did upload a new version of the program and source. Found a really stupid mistake that only occured when the int is at a minimum max value.
I also put the test function in the source to check if IntToStr is outputting correctly all the time. I am doing the positive numbers now and it may take days to finish just the positive. Maybe to save time, someone else could do the negative and report back.
http://foryouandi.com/Programs/index.php