v8裡一段很巧妙的帶cache的字元型別判斷模板類

2021-04-29 02:00:42 字數 1350 閱讀 5594

編譯過程經常需要判斷字元的型別。

有些判斷很簡單,數字就是['0','9'],字幕就是['a','z']和['a','z']。幾個比較語句就搞定了。

有些比需要比較多的判斷次數,因為他們是乙個不連續的編碼的字元集合。像最常見的空字元集合,。

遇到這種集合就只能逐個比較。可以通過對集合排序,減少比較次數,但是比較的平均次數仍然和這個集合的大小成正比。(假設每個字元出現的概率一樣)。

如果能引入乙個方法,把比較次數縮小成1,那麼整個掃瞄速度就可以提高。

v8引擎裡有乙個模板類,專門處理這個問題。

這個類通過cache,把比較次數縮小到1。而且把判斷邏輯和cache的邏輯分離。可以適用任何字元集合判斷。

template

class predicate

inline bool get(uchar c);

private:

friend class test;

bool calculatevalue(uchar c);

struct cacheentry

inline cacheentry(uchar code_point, bool value)

: code_point_(code_point),

value_(value)

uchar code_point_ : 21;

bool value_ : 1;

};static const int ksize = size;

static const int kmask = ksize - 1;

cacheentry entries_[ksize];

};模板引數t是實現判斷邏輯的類。size是cache大小,這個數字一定要是2的冪,預設值其實足夠好了。

這個predicte的工作方式很簡單,先找找cache裡有這個字元嗎,有則返回cache,沒有,判斷一下,記錄新的結果,記錄到cache裡。

template bool predicate::get(uchar code_point)

template bool predicate::calculatevalue(

uchar code_point)

這裡可以看出cache的分配是通過掩碼進行的,實際上就是看這個多位元組字元(uchar是int)的最後幾位來 分配。掩碼kmask是根據模板引數求得。如果size是256那掩碼就是求最後乙個位元組。cacheentry儲存了最後一次比較資訊。可以檢查出衝突 (兩個字元占用同乙個cache),以最後一次比較優先記錄。t類提供靜態成員方法is來判斷字元是否屬於這個集合。

整個方法可以看作是乙個hash表開放位址發的變形。希望通過一次雜湊查詢,替代集合運算。如果這個集合判斷十分簡單,比如數字,反而沒必要這麼做了。

一段很搞笑的排序演算法

public class sleepsort sortthread sortthreads new sortthread ints.length for int i 0 i sortthreads.length i for int i 0 i sortthreads.length i class s...

V8引擎對JS陣列的一些實現優化

vart newarray 200000 console time time1 for vari 0 i 200000 i console timeend time1 vart console time time2 for vari 0 i 200000 i console timeend time...

回顧大學裡堅持的一段時期的日記,以及現階段的思考

大學裡我是不是一事無成,時間其實就是被我自己給不斷的思考,而沒有去做給耗費掉的,以我現在的認知,應該先去做,再思考,否則你永遠不會邁不出第一步。我恐懼什麼?我希望做什麼?接下來我應該做什麼?個人對於工作閒散的時候是相當恐懼的,認為自己在耗費生命,這也是我開始新的日記之旅的原因。無意中發現給自己提問的...