Size_t <br/> strlen (str) <br/> const char * str; <br/>{< br/> const char * char_ptr; <br/> const unsigned long int * longword_ptr; <br/> unsigned long int longword, himagic, lomagic; <br/>/* Handle the first few characters by reading one character at a time. <br/> Do this until CHAR_PTR is aligned on a longword boundary. */<br/> for (char_ptr = str; (unsigned long int) char_ptr <br/> & (sizeof (long Word)-1 ))! = 0; <br/> ++ char_ptr) <br/> if (* char_ptr = '/0') <br/> return char_ptr-str; <br/>/* All these elucidatory comments refer to 4-byte longwords, <br/> but the theory applies equally well to 8-byte longwords. */<br/> longword_ptr = (unsigned long int *) char_ptr; <br/>/* Bits 31, 24, 16, and 8 of this number are zero. call these bits <br/> the "holes. "Note that there is a hole just to the left Of <br/> each byte, with an extra at the end: <br/> bits: 01111110 11111110 11111110 11111111 <br/> bytes: aaaaaaaa bbbbbbbb cccccccc dddddddd <br/> The 1-bits make sure that carries propagate to the next 0-bit. <br/> The 0-bits provide holes for carries to fall. */<br/> himagic = 0x80808080L; <br/> lomagic = 0x01010101L; <br/> if (sizeof (longword)> 4) <br/> {<br/>/* 64-bit version of t He magic. */<br/>/* Do the shift in two steps to avoid a warning if long has 32 bits. */<br/> himagic = (himagic <16) <16) | himagic; <br/> lomagic = (lomagic <16) <16) | lomagic; <br/>}< br/> if (sizeof (longword)> 8) <br/> abort (); <br/>/* Instead of the traditional loop which tests each character, <br/> we will test a longword at a time. the tricky part is testing <br/> if * any Of the four * bytes in the longword in question are zero. */<br/> for (;) <br/>{< br/> longword = * longword_ptr ++; <br/> if (longword-lomagic) &~ Longword & himagic )! = 0) <br/>{< br/>/* Which of the bytes was the zero? If none of them were, it was <br/> a misfire; continue the search. */<br/> const char * cp = (const char *) (longword_ptr-1); <br/> if (cp [0] = 0) <br/> return cp-str; <br/> if (cp [1] = 0) <br/> return cp-str + 1; <br/> if (cp [2] = 0) <br/> return cp-str + 2; <br/> if (cp [3] = 0) <br/> return cp-str + 3; <br/> if (sizeof (longword)> 4) <br/>{< br/> if (cp [4] = 0) <br/> return cp-str + 4; <br/> if (cp [5] = 0) <br/> return cp-str + 5; <br/> if (cp [6] = 0) <br/> return cp-str + 6; <br/> if (cp [7] = 0) <br/> return cp-str + 7; <br/>}< br/>}
The main idea is to convert a character that reads one byte into a string that reads 4/8 bytes each time, improving the efficiency.
Judge whether the character is 0 one by one. If the character is 0, exit. The code is concise, and the performance is not low. It is a little inadequate. On a computer with a 4-byte or 8-byte length
Reading one byte is a waste of computer capabilities. If you read four or eight bytes each time, the total number of reads will be greatly reduced. When you read four or eight bytes
If the address is not on the boundary, the machine will have to read it twice. This will reduce the performance and weaken the optimization effect. Therefore, the first few characters must be processed separately.
Read 4 or 8 bytes each time starting from the long boundary address.
Method:
1. The first several bytes are processed separately.
For (char_ptr = str; (unsigned long int) char_ptr <br/> & (sizeof (longword)-1 ))! = 0; <br/> ++ char_ptr) <br/> if (* char_ptr = '/0') <br/> return char_ptr-str;
2. 4-byte or 8-byte processing in the middle
3. If there is zero in the middle, it will be processed separately.
If (longword-lomagic )&~ Longword & himagic )! = 0) <br/>{< br/>/* Which of the bytes was the zero? If none of them were, it was <br/> a misfire; continue the search. */<br/> const char * cp = (const char *) (longword_ptr-1); <br/> if (cp [0] = 0) <br/> return cp-str; <br/> if (cp [1] = 0) <br/> return cp-str + 1; <br/> if (cp [2] = 0) <br/> return cp-str + 2; <br/> if (cp [3] = 0) <br/> return cp-str + 3; <br/> if (sizeof (longword)> 4) <br/>{< br/> if (cp [4] = 0) <br/> return cp-str + 4; <br/> if (cp [5] = 0) <br/> return cp-str + 5; <br/> if (cp [6] = 0) <br/> return cp-str + 6; <br/> if (cp [7] = 0) <br/> return cp-str + 7; <br/>}< br/>}
It looks good, but there is another problem: how to ensure that all 0 bytes exist when reading 4 or 8 bytes, because 0 is used to indicate the end of the string.
The key to optimization is to determine whether all 0 bytes exist in several consecutive bytes. We cannot judge one byte or one byte, because the optimization idea is to read
Multiple bytes to reduce the total number of reads. If you judge each byte separately, the optimization will be lost.
What should we do? Of course, bit operations are considered first.
* What are the characteristics of a pure 0 byte? Obviously, every bit is 0, and every bit is 1 after bitwise inversion.
* What are the other features of a zero-byte? This byte minus 1, must borrow 1 from a higher byte. After borrowing 1, the maximum bit of this Byte must be 1.
Taking the 4-byte integer n as an example, we only need to subtract 1 from each byte. If a pure 0 byte exists, there will inevitably be a bits.
The maximum byte value is 1. You only need to determine whether the maximum bit of each byte exists 1. However, there is another problem: In this 4-byte integer,
Some bytes may have a maximum of 1, so these bytes must be excluded.
Solution:
* Subtract 1 from each byte of n and get the highest bit to get x. If there is a borrow bit, the highest bit of this byte is 1.
* Reverse each byte of n and retrieve the highest bit. The highest bit of y and y is 1, indicating that it is 0 in n.
* Bitwise and operation of x and y. If the value is not equal to 0, it means that n has at least 1 byte. The original highest bit is not 1, and then it becomes 1, that is, the borrow bit.
If n contains all 0 bytes, x & y must not be 0, because the maximum bit of the borrowed byte will be set to 1.
If n does not contain all 0 bytes, no borrow space is generated. x & y is equal to 0.
X & y = (n-0x01010101 )&~ N & amp; 0x80808080
Reference: http://topic.csdn.net/u/20091029/18/8f047493-15f8-4af5-bb8d-b5147128f79a.html
Http://simohayha.javaeye.com/blog/439059
Http://bigwhite.blogbus.com/logs/37753065.html