lua設計與實現(三)字串

2021-08-30 09:00:16 字數 3117 閱讀 4786

lua字串內化的優點:

傳統字串的比較與查詢是根據字串長度逐位比較,時間複雜度與字串長度線性相關。而lua的,在已知字串雜湊值的情況下,只需要一次整數比較。

多份相同的字串在整個系統中只存在乙份副本。

缺點:

以前面描述的建立字串的過程來說,在建立乙個新的字串時,首先會檢查系統中是否有相同的資料,只有不存在的情況下才建立,這與直接建立字串相比,多了一次查詢過程好在在lua的實現中,查詢乙個字串的操作消耗並不算大。

字串的資料結構定義:

/*** string headers for string table

*/typedef

union tstring tsv;

} tstring;

可以看到這是乙個聯合體,其目的是為了讓tstring資料型別按照l_umaxalign 型別的大小對齊

/* type to ensure maximum alignment */

typedef luai_user_alignment_t l_umaxalign;

/*@@ luai_user_alignment_t is a type that requires maximum alignment.

** change it if your system requires alignments larger than double. (for

** instance, if your system supports long doubles and they must be

** aligned in 16-byte boundaries, then you should add long double in the

** union.) probably you do not need to change this.

*/#define luai_user_alignment_t union

在c語言中struct/union這樣的復合資料型別是按照這個型別中最大的資料來對齊的,所以這裡就按照double來對齊,一般是8位元組。之所以要進行對齊操作,是為了cpu讀取資料時效能更高。

tstring其餘變數的含義:

lua存放字串的全域性變數就是global_state的strt成員,這是乙個雜湊陣列,專門用於存放字串:

typedef

struct stringtable stringtable;

當新建乙個字串元素tstring時,首先計算出字串的雜湊值,這就是雜湊陣列的索引,如果這裡已有元素,則使用鍊錶串接起來。如圖

使用雜湊桶存放資料,有乙個問題需要考慮,那就是當資料量非常大的時候,分配到每個桶上的資料也會非常多,那麼一次查詢又會退化為線性查詢。所以需要乙個重新雜湊(rehash)的過程,這就是當字串非常多的時候,重新分配桶的數量,降低分配到每個桶的資料數量,這個過程在函式luas_resize中。

void luas_resize (lua_state *l,

int newsize)

}luam_freearray

(l, tb->hash, tb->size, tstring *);

tb->size = newsize;

tb->hash = newhash;

}

gcssweepstring:當前gc處在**字串資料階段。

觸發這個resize操作的地方有兩個:

分配乙個新的字串,**在luas_newlstr:

static tstring *newlstr (lua_state *l,

const

char

*str, size_t l,

unsigned

int h)

tstring *luas_newlstr (lua_state *l,

const

char

*str, size_t l)

}return

newlstr

(l, str, l, h)

;/* not found */

}

(1)計算需要新建立的字串對應的雜湊值。計算步長是為了 字串非常大的時候不需要逐位來算,僅需要每個步長取乙個字元就可以了

(2)根據雜湊值找到對應的雜湊桶,遍歷該雜湊桶的所有元素,如果能夠查詢到同樣的字串,說明之前已經存在相同字串,此時不需要重新分配乙個新的字串資料,直接返回即可

(3)如果第(2)步中查詢不到相同的字串,呼叫newlstr函式建乙個新的字串。

最後,reserved欄位,用於標識是不是保留字串。lua中的關鍵字都是保留字串,最開始賦值:

void luax_init (lua_state *l)

}

這裡reserved存放的是陣列luax_tokens的索引,這樣,一方面可以快速定位到哪個關鍵字,另一方面,如果不為0,則是保留字串。

/* order reserved */

const

char

*const luax_tokens =

;

這裡的每個字串都與某個保留字token型別一一對應:

/** warning: if you change the order of this enumeration,

* grep "order reserved"

*/enum reserved

;

需要說明的是,上面luax_tokens字串陣列中的氣number, name, string, eof,

這幾個字串並不真實作為保留關鍵字存在,但是因為有相應的保留字token型別,所以也就乾脆這麼定義個對應的字串了。

有了以上認知,不難理解在lua中,應該盡量少地使用字串連線操作符,因為每次都會生成個新的字串。

三 字串 一

三 字串 1。直接量三種寫法 1 單引號,不會替換變數,且只支援 兩個轉譯字元 2 雙引號,會進行變數替換,雙引號能支援除了 以外的所有轉譯符 3 heredoc,比如 string end of string haha hehe hoho.hehe end of string 其中end of s...

三 字串操作

windows核心編碼字符集採用unicode字符集,字串處理使用unicode string,是乙個結構體,定義如下 typedef struct unicode string unicode string length 字串長度,maximumlength 字串緩衝區長度,buffer 字串緩衝...

三 字串補充

1 輸出函式中的字串的格式化 之前有簡單地使用了說明了prin函式中字串的拼接。name xiong age 21 男 high 175weight 56 print 我姓 s,性別 s,今年 s歲,身高 scm,體重 skg。name,age,high,weight 為了保證絕對正確。只需要將上面...