当前位置:网站首页>Analysis of glibc strlen implementation mode
Analysis of glibc strlen implementation mode
2022-07-05 03:38:00 【Maple tree】
Abstract
This paper deals with glibc 2.35 In the source strlen
Research on function implementation , The principle of using bit operation to realize faster length calculation is analyzed .
Function position
glibc-2.35/string/strlen.c
Original implementation
Here is glibc strlen.c File contents of :
/* Copyright (C) 1991-2022 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */
#include <string.h>
#include <stdlib.h>
#undef strlen
#ifndef STRLEN
# define STRLEN strlen
#endif
/* Return the length of the null-terminated string STR. Scan for the null terminator quickly by testing four bytes at a time. */
size_t
STRLEN (const char *str)
{
const char *char_ptr;
const unsigned long int *longword_ptr;
unsigned long int longword, himagic, lomagic;
/* Handle the first few characters by reading one character at a time. Do this until CHAR_PTR is aligned on a longword boundary. */
for (char_ptr = str; ((unsigned long int) char_ptr
& (sizeof (longword) - 1)) != 0;
++char_ptr)
if (*char_ptr == '\0')
return char_ptr - str;
/* All these elucidatory comments refer to 4-byte longwords, but the theory applies equally well to 8-byte longwords. */
longword_ptr = (unsigned long int *) char_ptr;
/* Bits 31, 24, 16, and 8 of this number are zero. Call these bits the "holes." Note that there is a hole just to the left of each byte, with an extra at the end: bits: 01111110 11111110 11111110 11111111 bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD The 1-bits make sure that carries propagate to the next 0-bit. The 0-bits provide holes for carries to fall into. */
himagic = 0x80808080L;
lomagic = 0x01010101L;
if (sizeof (longword) > 4)
{
/* 64-bit version of the magic. */
/* Do the shift in two steps to avoid a warning if long has 32 bits. */
himagic = ((himagic << 16) << 16) | himagic;
lomagic = ((lomagic << 16) << 16) | lomagic;
}
if (sizeof (longword) > 8)
abort ();
/* Instead of the traditional loop which tests each character, we will test a longword at a time. The tricky part is testing if *any of the four* bytes in the longword in question are zero. */
for (;;)
{
longword = *longword_ptr++;
if (((longword - lomagic) & ~longword & himagic) != 0)
{
/* Which of the bytes was the zero? If none of them were, it was a misfire; continue the search. */
const char *cp = (const char *) (longword_ptr - 1);
if (cp[0] == 0)
return cp - str;
if (cp[1] == 0)
return cp - str + 1;
if (cp[2] == 0)
return cp - str + 2;
if (cp[3] == 0)
return cp - str + 3;
if (sizeof (longword) > 4)
{
if (cp[4] == 0)
return cp - str + 4;
if (cp[5] == 0)
return cp - str + 5;
if (cp[6] == 0)
return cp - str + 6;
if (cp[7] == 0)
return cp - str + 7;
}
}
}
}
libc_hidden_builtin_def (strlen)
analysis
It is different from comparing whether each character is 0,glibc Of strlen Use every 8 byte (64 Bit program ) A way of comparison , Find it quickly as 0 Bytes of . after , To contain 0 Of 8 Byte by byte comparison within bytes , find 0 The location of .
alignment
To improve efficiency , First, compare the first few characters one by one , Until the pointer and long Type address alignment .
const char *char_ptr;
const unsigned long int *longword_ptr;
unsigned long int longword, himagic, lomagic;
/* Handle the first few characters by reading one character at a time. Do this until CHAR_PTR is aligned on a longword boundary. */
for (char_ptr = str; ((unsigned long int) char_ptr
& (sizeof (longword) - 1)) != 0;
++char_ptr)
if (*char_ptr == '\0')
return char_ptr - str;
/* All these elucidatory comments refer to 4-byte longwords, but the theory applies equally well to 8-byte longwords. */
longword_ptr = (unsigned long int *) char_ptr;
Comparison principle
after , Each 8 The principle of bit one comparison .
If a byte is all 0, That is to say 00000000( Binary system ). that , If we subtract it 1 The operation of , It will become 11111111.
Pay attention to the highest position . If we put the original byte 0 To reverse , What you get is 11111111, Then take and operate the two results , The resulting value will be the highest bit 1 Value . Be careful , Even if the byte immediately following it needs to borrow when subtracting , This byte will only become 11111110, The highest position is still 1.
If this byte is not all 0, There are two situations : The first is 1 And the first is 0.
If the first byte is 0, Then it is 0abcdef,a-f At least there is 1 A for 1, So subtract... From the lowest order 1 after , The first is still 0.
If the first byte is 1, And it is the only binary representation of this byte 1, Then subtract 1 In operation , The first place will become 0. If it's not the only one 1, Then the first place is still 1.
Above all , It can be seen that , If the lowest bit of a byte is subtracted 1 after , The highest bit is 1, And the highest bit after byte inversion is also 1, Then this byte must be 0. Based on this , We can compare bytes in batches .
for (;;) {
longword = *longword_ptr++;
if (((longword - lomagic) & ~longword & himagic) != 0) {
/* Which of the bytes was the zero? If none of them were, it was a misfire; continue the search. */
const char *cp = (const char *) (longword_ptr - 1);
if (cp[0] == 0)
return cp - str;
if (cp[1] == 0)
return cp - str + 1;
if (cp[2] == 0)
return cp - str + 2;
if (cp[3] == 0)
return cp - str + 3;
if (sizeof (longword) > 4) {
if (cp[4] == 0)
return cp - str + 4;
if (cp[5] == 0)
return cp - str + 5;
if (cp[6] == 0)
return cp - str + 6;
if (cp[7] == 0)
return cp - str + 7;
}
}
}
边栏推荐
- Delphi free memory
- Delphi read / write JSON format
- The perfect car for successful people: BMW X7! Superior performance, excellent comfort and safety
- New interesting test applet source code_ Test available
- What is the most effective way to convert int to string- What is the most efficient way to convert an int to a String?
- Difference between MotionEvent. getRawX and MotionEvent. getX
- 問下,這個ADB mysql支持sqlserver嗎?
- Easy processing of ten-year futures and stock market data -- Application of tdengine in Tongxinyuan fund
- speed or tempo in classical music
- Logstash、Fluentd、Fluent Bit、Vector? How to choose the appropriate open source log collector
猜你喜欢
Leetcode92. reverse linked list II
[vérification sur le Web - divulgation du code source] obtenir la méthode du code source et utiliser des outils
Azkaban installation and deployment
error Couldn‘t find a package.json file in “你的路径“
[105] Baidu brain map - Online mind mapping tool
Mongodb common commands
Basic knowledge of tuples
[groovy] loop control (number injection function implements loop | times function | upto function | downto function | step function | closure can be written outside as the final parameter)
Linux Installation redis
【web源码-代码审计方法】审计技巧及审计工具
随机推荐
Talk about the SQL server version of DTM sub transaction barrier function
[deep learning] deep learning reference materials
C file in keil cannot be compiled
Share the newly released web application development framework based on blazor Technology
LeetCode146. LRU cache
Delphi free memory
Basic authorization command for Curl
Sqoop command
IPv6 experiment
How rem is used
1. Five layer network model
SQL performance optimization skills
Anti debugging (basic principles of debugger Design & NT NP and other anti debugging principles)
【软件逆向-基础知识】分析方法、汇编指令体系结构
問下,這個ADB mysql支持sqlserver嗎?
KVM virtualization
MySQL winter vacation self-study 2022 11 (10)
Binary heap implementation (priority queue implementation)
New interesting test applet source code_ Test available
线程基础知识