字串轉化為數值

2021-05-28 13:18:21 字數 2381 閱讀 5889

工作時遇到這樣的乙個情況:伺服器a向b傳送請求並接受結果,耗時300ms,伺服器b從接受請求到傳送完畢,耗時100ms。由於是內網,不可能有200ms的網路延遲。後經檢測,是因為傳輸時用的是字串格式,解析時用了sscanf造成的。

由於sscanf要考慮到變參問題,並且接受的種類更加豐富(相對於strto*函式族),所以會很慢,之前我以為scanf函式族慢是因為io,現在看來當時的看法很幼稚。經過測試對比,發現還是手工編寫的有針對性的**速度更快。測試**如下(其中測時類timer是我自己定義的,用的rdtsc取cpu的cycle)

#include #include #include "utility.d/timing.d/timing.h"

#define n 30000

int table[256];

int* ptable = table + 128;

void

init_table()

#define str2i_table( str, rst ) \

dowhile(0)

inline int

str2l( char* str )

int main()

開優化 -o2時,輸出如下:

sscanf cost : 13705800 -123456

strtol cost : 2819204 -123456

atoi cost : 2692044 -123456

str2l cost : 735160 -123456

str2i_table cost : 828984 -123456

可以看到,只轉化整數,還是手工會快很多。但是查表法str2i_table還是稍慢於直接轉化str2l的。

另外我在想能否將rst*10優化,如上面我注釋掉的**,將乙個乘法轉化為兩個移位與乙個加法,結果出乎意料,用這個方法反而更慢了。看來編譯器能做的優化遠遠超出我的想象啊。於是我將其編譯成彙編**,看了一下區別。

rst = rst * 10 + ( *str++ - '0' );

16 leal (%rcx,%rcx,4), %eax

# %rcx = rst, 所以這一句是 %eax = rst + rst * 4 = rst * 5

17 movsbl %dl,%edx

# %dl = *str, 將其按有符號擴充套件到%edx

18 leal -48(%rdx,%rax,2), %ecx

# %ecx (存放rst) = %rdx ( 存放*str ) + %rax ( 存放rst的5倍 ) * 2 - 48 ( 這是'0' )

rst = (rst<<3) + (rst<<1) + ( *str++ - '0' );

16 leal (%rcx,%rcx), %eax

# %rcx = rst, 這一句是 %eax = %rcx + %rcx = rst * 2

17 movsbl %dl,%edx

# %dl = *str, 將其按有符號擴充套件到%edx

18 leal -48(%rax,%rcx,8), %eax

# %eax = %rax + %rcx * 8 - 48 = rst * 2 + rst * 8 - '0' = rst * 10 - '0'

19 leal (%rax,%rdx), %ecx

# %ecx (存放rst) = %rax ( rst * 10 - '0') + %rdx ( 存放符號擴充套件的*str )

多出了一條lea指令,所以會變慢。

lea和mov的opcode都是乙個位元組,區別就是

leal (ebx), eax   <==>  movl ebx, eax

但是由於lea指令是載入有效位址,裡面按照base+index*scale+displacement,一條指令可以直接計算兩個加法和乙個乘法,可以用這個特點做一些算術運算,當然,要求乘法因子scale必須是2的冪。例如:

leal    -48(%rdx,%rax,2), %ecx

就是乙個很好的例子,base = %rdx, index = %rax, scale = 2,displacement = -48,這些運算都直接集中在一條指令裡了。

如果對彙編指令有疑問,可以參看以下這篇文章,講述了intel和at&t格式的一些區別。

字串轉化為整數值

思路分析 首先判斷字串是否為空,返回0 考慮前面的是否是空格,使用trim 去掉,然後判斷長度是否為0,是的話,返回0 判斷第乙個字元是不是 和 設定變數sign記錄 迴圈取得字串的數字,考慮字串中有非數字,遇到就退出,保留前面的數字 考慮溢位的情況,溢位返回integer的最大值或最小值 publ...

字串轉化為陣列,陣列轉化為字串。

做題中常遇到字串轉化為數字,數字轉化為字串等,自己轉化比較麻煩,c語言提供了幾個標準庫函式,可以將任意型別 整型 長整型 浮點型等 的數字轉換為字串。1.整數轉化為字串。itoa include include int main itoa 函式有3個引數 第乙個引數是要轉換的數字,第二個引數是要寫入...

整數轉化為字串和字串轉化為整數

整數轉化為字串 includeint main temp i 0 為什麼等於0就可以,因為將temp定義為字串陣列後,等號右邊的數相當於ascii碼值,0就相當於 0 如果寫為61,輸出就為 12345 printf s temp i i 1 while i 0 str j temp i str j...