Skip to content

Commit be2ce79

Browse files
committed
Optimize _byteCount with compiler intrinsics
Use compiler intrinsics to make _byteCount faster
1 parent 8a9b69b commit be2ce79

File tree

1 file changed

+16
-13
lines changed

1 file changed

+16
-13
lines changed

CoreFoundation/Parsing.subproj/CFBinaryPList.c

+16-13
Original file line numberDiff line numberDiff line change
@@ -519,22 +519,25 @@ static void _flattenPlist(CFPropertyListRef plist, CFMutableArrayRef objlist, CF
519519
/* Get the number of bytes required to hold the value in 'count'. Will return a power of 2 value big enough to hold 'count'.
520520
*/
521521
CF_INLINE uint8_t _byteCount(uint64_t count) {
522-
uint64_t mask = ~(uint64_t)0;
523-
uint8_t size = 0;
524522

525-
// Find something big enough to hold 'count'
526-
while (count & mask) {
527-
size++;
528-
mask = mask << 8;
529-
}
523+
if (count == 0)
524+
return 1; // Special case 0 since it is undefined for __builtin_clzll
530525

531-
// Ensure that 'count' is a power of 2
532-
// For sizes bigger than 8, just use the required count
533-
while ((size != 1 && size != 2 && size != 4 && size != 8) && size <= 8) {
534-
size++;
535-
}
526+
// Count the number of leading 0s and subtract from the max value, which is 64
527+
int zeroCount = 64 - __builtin_clzll(count);
528+
529+
// Round to highest by 8 number
530+
zeroCount += -zeroCount & 7;
531+
532+
// Divide by 8
533+
zeroCount >>= 3;
534+
535+
// Anything 8 or above just use the zeroCount
536+
if (zeroCount >= 8)
537+
return zeroCount;
536538

537-
return size;
539+
// calculate nearest power of 2;
540+
return 1U << (32 - __builtin_ctz(zeroCount - 1));
538541
}
539542

540543
// stream can be a CFWriteStreamRef (on supported platforms) or a CFMutableDataRef

0 commit comments

Comments
 (0)