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 為了保證絕對正確。只需要將上面...