CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Int32 to string conversion; fastest itoa

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Torello



Joined: 29 Sep 2006
Posts: 118

View user's profile Send private message

Int32 to string conversion; fastest itoa
PostPosted: Fri Jan 02, 2009 2:57 am     Reply with quote

Hi,

First, best wishes to everybody on this forum. A C-full 2009!

Tweaking my application to the minimum energy consumption (thus also execution speed of a task), I found out that sprintf 4 int32 values take up about 92 ms (18LF4620 @4Mhz)! Quite shocked!

Replaced the sprintf with the use of ccs-itoa, but that did not make any difference; probably sprintf uses ccs-itoa. Then took a look at the standard-c itoa. It is using the % (mod) operator heavily. The code looks very resources efficient. I've come up with an replacement below. Uses probably more recourses, but It does the same 4 int32 in 10ms!. So nine times faster. Or 90% discount on energy consumption. Heh, thats worth while spending on a little more bytes.

Can we make this function still faster? Or has somebody an other, faster routine to share?

Regards,
Edwin



Code:
//==============================================================================
// Function converts int32 to signed decimal string
// returns pointer to the '/0' ended string. (handy for formatting more values)

char *i32toa(int32 n, char *s) {
  int8 i,j;                    //decade counter
  int8 idx=0;                  //string index     
  int32 const Div[10] = {      //decades table
    1000000000L,100000000L,10000000L,1000000L
    100000L,10000L,1000L,100L,10L,1};   
  int32 b;                     //i32 to hold table read                           
  int fdd;                     //first digit detect (suppress leading zero function)
 
  fdd=0;                       //clear detection
  if (bit_test(n,31)) {        //T: n=negative
    n=(~n)+1;                  //convert to positive
    s[0]='-';                  //mark the negative number
    idx++;
  } 
 
 
  for (i=0; i<10;i++) {        //do all the decades, start with biggest
    j=0;                       //clear the decimal digit counter
    b=Div[i];                  //read the table once;
    while (n>=b) {             //T: "left-over" still bigger then decade; substr. and count
      j++;
      n-=b;
    } 
    if ((j)||(fdd)) {          //T: decade count!=0 or first digit has been detected
      fdd=1;
      s[idx++]='0'+j;          //..then add the decade count
    } 
  }

  if (!fdd) s[idx++]='0';      //dont suppress zero when n==0!
  s[idx]=0;                    //end the string
  return(s+idx);               //return last written pointer
}

//=== code snippet to format 4 int32 into string  with comma as separator
i320=-2139999999L;
i321=-2139999999L;
i322=-2139999999L;
i323=-2139999999L;
#ifdef _DM output_high(pin_b3); #endif                     
ptS = i32toa(i320,tS);
*(ptS++)=',';
ptS = i32toa(i321,ptS);
*(ptS++)=',';
ptS = i32toa(i322,ptS);
*(ptS++)=',';
ptS = i32toa(i323,ptS);                  //total 10ms
#ifdef _DM output_low(pin_b3); #endif     
fprintf(debug,"%s\n",tS);


Ttelmah
Guest







PostPosted: Fri Jan 02, 2009 3:14 am     Reply with quote

You might find a more efficient '%', with a search here. Though things may have changed.
CCS, 'waste' a lot of time in several places using %. Their implementation, performs a division, then takes the integer part of the result, and multiplies this, subtracting this result from the original to get the %. In many places, they perform this, and a division again, as well, to get the part needed for the next operation!.....
A long time ago, I found that in fact their division code, had the remainder already present in a temporary store, and the two divisions, and one multiplication used to get the values needed, could be replaced with just one division, if you accessed this. I posted a routine to do this. It was though a long time ago (probably on the old board), and I have no idea what the thread was called, but a search might find it. Made a massive difference to the performance...

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group