js字符串最多存儲(chǔ)多少字節(jié)鳍寂?

js字符串最多存儲(chǔ)多少字節(jié)?

V8的heap上限只有2GB不到闻葵,允許分配的單個(gè)字符串大小上限更只有大約是512MB不到民泵。JS字符串是UTF16編碼保存,所以也就是2.68億個(gè)字符槽畔。FF大約也是這個(gè)數(shù)字栈妆。

https://www.zhihu.com/question/61105131

JavaScript字符串底層是如何實(shí)現(xiàn)的?

作者:RednaxelaFX

鏈接:https://www.zhihu.com/question/51132164/answer/124450796

來源:知乎

著作權(quán)歸作者所有厢钧。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)鳞尔,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

目前主流的做法是把String值的實(shí)現(xiàn)分為5大類使用場(chǎng)景:

  1. 已經(jīng)要查看內(nèi)容的字符串:使用flat string思路來實(shí)現(xiàn)早直,本質(zhì)上說就是用數(shù)組形式來存儲(chǔ)String的內(nèi)容寥假;
  2. 拼接字符串但尚未查看其內(nèi)容:使用“rope”思路或其它延遲拼接的思路來實(shí)現(xiàn)。當(dāng)需要查看其內(nèi)容時(shí)則進(jìn)行“flatten”操作將其轉(zhuǎn)換為flat string表現(xiàn)形式莽鸿。最常見rope的內(nèi)部節(jié)點(diǎn)就像二叉樹(RopeNode { Left; Right })一樣昧旨,但也可以有采用更多叉樹的設(shè)計(jì)的節(jié)點(diǎn)拾给,或者是用更動(dòng)態(tài)的多叉樹實(shí)現(xiàn)祥得;
  3. 子串(substring):使用“slice”思路來實(shí)現(xiàn),也就是說它只是一個(gè)view蒋得,自己并不存儲(chǔ)字符內(nèi)容而只是記錄個(gè)offset和length级及,底下的存儲(chǔ)共享自其引用的源字符串;
  4. 值得駐留(intern)的字符串:通常也是flat string但可能會(huì)有更多的限制额衙,存儲(chǔ)它的空間可能也跟普通String不一樣饮焦。最大的好處是在特殊場(chǎng)景下有些字符串會(huì)經(jīng)常重復(fù)出現(xiàn),或者要經(jīng)常用于相等性比較窍侧,把這些字符串駐留起來可以節(jié)省內(nèi)存(內(nèi)容相同的字符串只駐留一份)县踢,并且后續(xù)使用可以使用指針比較來代替完全的相等性比較(因?yàn)轳v留的時(shí)候已經(jīng)比較過了);
  5. 外來字符串:有時(shí)候JavaScript引擎跟外界交互伟件,外界想直接把一個(gè)char8_t或者char16_t傳給JavaScript引擎當(dāng)作JavaScript字符串用硼啤。JavaScript引擎可能會(huì)針對(duì)某些特殊場(chǎng)景提供一種包裝方式來直接把這些外部傳進(jìn)來的字符串當(dāng)作JavaScript String,而不拷貝其內(nèi)容斧账。

在上述5種場(chǎng)景中谴返,涉及存儲(chǔ)的時(shí)候都可以有

  • 使用UTF-16為單元的最常規(guī)做法以及使用Latin-1 / ASCII的壓縮版本這兩種變種煞肾。
  • 對(duì)于flat string,直接把字符串內(nèi)容粘在對(duì)象末尾的“內(nèi)嵌版”嗓袱,以及把字符串內(nèi)容放在獨(dú)立的數(shù)組里的“獨(dú)立數(shù)組版”兩個(gè)變種籍救。

如果把語言層面的一個(gè)String值類型按上述使用場(chǎng)景給拆分成若干種不同的底層實(shí)現(xiàn)類型,本質(zhì)上都是在為內(nèi)存而優(yōu)化:要么是減少String的內(nèi)存使用量(1-byte vs 2-byte渠抹、substring等)蝙昙,要么是減少拷貝的次數(shù)/長(zhǎng)度(rope的按需flatten)。

底層實(shí)現(xiàn)類型的數(shù)量的增多梧却,會(huì)使得相關(guān)處理的代碼都變得多態(tài)耸黑,不利于編譯器對(duì)其做優(yōu)化,所以這里是有取舍的篮幢。如果多態(tài)換來的內(nèi)存收益比不上多態(tài)的代碼開銷的話就得不償失了大刊。顯然,眾多JavaScript引擎都選擇了在String值類型上細(xì)分出多種實(shí)現(xiàn)類型三椿,反映了多態(tài)在這個(gè)地方總體來看是有利的缺菌。

把上面的場(chǎng)景(1)、(2)搜锰、(3)用代碼來舉例:

var s1 = "rednaxela"; // flat string, string literal

var s2 = "fx"; // flat string, string literal

var s3 = s1 + s2; // rope ("concat string", "cons string")

var s4 = s3.substring(0, 3); // substring / slice

// 這個(gè)操作可能會(huì)讓s3所引用的String值被flatten為flat string

// 同理伴郁,如果執(zhí)行 s3[0] 下標(biāo)操作也可能會(huì)讓原本是rope的String值被flatten

在有用rope來優(yōu)化字符串拼接的JavaScript引擎上,使用二元+運(yùn)算符來拼接字符串其實(shí)不會(huì)直接導(dǎo)致冗余的字符串內(nèi)容拷貝蛋叼,只有在需要使用字符串的內(nèi)容時(shí)才會(huì)對(duì)它做一次批量的flatten操作焊傅,做一次拷貝。所以字符串拼接“要用Array.prototype.join()而忌諱用+運(yùn)算符”的建議就不那么重要了狈涮。

=========================================

V8

于是讓我們來考察一下V8的String都有上述場(chǎng)景的哪些狐胎。

針對(duì)5.5.339版本來看:

v8/objects.h at 5.5.339 · v8/v8 · GitHub

// - Name

// - String

// - SeqString

// - SeqOneByteString

// - SeqTwoByteString

// - SlicedString

// - ConsString

// - ExternalString

// - ExternalOneByteString

// - ExternalTwoByteString

// - InternalizedString

// - SeqInternalizedString

// - SeqOneByteInternalizedString

// - SeqTwoByteInternalizedString

// - ConsInternalizedString

// - ExternalInternalizedString

// - ExternalOneByteInternalizedString

// - ExternalTwoByteInternalizedString

// - Symbol

V8里能表示字符串的C++類型有上面這么多種。其中Name是String(ES String Value)與Symbol(ES6 Symbol)的基類歌馍∥粘玻看看String類下面的子類是多么的豐富 >_<

簡(jiǎn)單說,String的子類都是用于實(shí)現(xiàn)ECMAScript的String值類型松却,從JavaScript層面看它們都是同一個(gè)類型——String暴浦,也就是說typeof()它們都會(huì)得到"string"。

其中:

  • SeqString就是上面的場(chǎng)景(1)(“flat string”)的實(shí)現(xiàn)晓锻。其中有SeqOneByteString / SeqTwoByteString分別對(duì)應(yīng)使用1-byte ASCII char與2-byte UTF-16的版本歌焦。字符串內(nèi)容都是直接粘在對(duì)象末尾的(“內(nèi)嵌版”)。

  • ConsString就是上面的場(chǎng)景(2)(“rope”)的實(shí)現(xiàn)砚哆。本質(zhì)上就是把還在拼接中的字符串用二叉樹(其實(shí)是二叉DAG)的方式先存著独撇,直到要查看其內(nèi)容時(shí)再flatten成SeqString。它自身不存儲(chǔ)字符內(nèi)容所以不關(guān)心1-byte還是2-byte。

  • SlicedString就是上面場(chǎng)景(3)(“slice / substring”)的實(shí)現(xiàn)券勺。同上它也不存儲(chǔ)字符內(nèi)容绪钥,所以1-byte還是2-byte就看引用的底層String是怎樣的。

  • ExternalString就是上面場(chǎng)景(5)(外部傳入的字符串)的實(shí)現(xiàn)关炼。這個(gè)涉及存儲(chǔ)程腹,所以也有1-byte與2-byte兩個(gè)實(shí)際實(shí)現(xiàn)。

  • InternalizedString系列就是上面場(chǎng)景(4)(“interned”)的實(shí)現(xiàn)儒拂。它的子類跟前面列舉的幾種類型一一對(duì)應(yīng)寸潦。

而String的包裝對(duì)象類型在V8里則是由StringWrapper來實(shí)現(xiàn):

bool HeapObject::IsStringWrapper() const {

return IsJSValue() && JSValue::cast(this)->value()->IsString();

}

值得注意的是:雖然ECMAScript的String值是值類型的,這并不就是說“String值就是在棧上的”社痛。

正好相反见转,V8所實(shí)現(xiàn)的String值全部都是在V8的GC堆上存儲(chǔ)的,傳遞String值時(shí)實(shí)際上傳遞的是指向它的指針蒜哀。但由于JavaScript的String值是不可變的斩箫,所以底層實(shí)現(xiàn)無論是真的把String“放在棧上”還是傳遞指針,對(duì)上層應(yīng)用的JavaScript代碼而言都沒有區(qū)別撵儿。

ExternalString雖然特殊但也不例外:它實(shí)際存儲(chǔ)字符串內(nèi)容的空間雖然是從外部傳進(jìn)來的乘客,不在V8的GC堆里,但是ExternalString對(duì)象自身作為一個(gè)對(duì)象頭還是在GC堆里的淀歇,所以該String類型實(shí)現(xiàn)邏輯上說還是在GC堆里易核。

話說V8除了上述String類型外,還有一些跟String相關(guān)的浪默、應(yīng)用于特殊場(chǎng)景的類型牡直。其中比較典型的有:

  • ReplacementStringBuilder:用于正則表達(dá)式的字符串替換等;

  • IncrementalStringBuilder:// TODO

這個(gè)版本的V8對(duì)自己字符串拼接實(shí)現(xiàn)已經(jīng)頗有信心纳决,所以 String.prototype.concat 也直接用JavaScript來實(shí)現(xiàn)了:

v8/string.js at 5.5.339 · v8/v8 · GitHub

// ECMA-262, section 15.5.4.6

function StringConcat(other /* and more */) { // length == 1

"use strict";

CHECK_OBJECT_COERCIBLE(this, "String.prototype.concat");

var s = TO_STRING(this);

var len = arguments.length;

for (var i = 0; i < len; ++i) {

s = s + TO_STRING(arguments[i]);

}

return s;

}

這就是直接把傳入的參數(shù)拼接成ConsString返回出去碰逸。

V8連標(biāo)準(zhǔn)庫(kù)函數(shù)都用這種代碼模式來實(shí)現(xiàn)了,同學(xué)們也不用擔(dān)心這樣做會(huì)太慢啦岳链。

而V8里的 Array.prototype.join 則針對(duì)稀疏數(shù)組的情況有些有趣的優(yōu)化:

它會(huì)借助一個(gè)臨時(shí)的InternalArray為“string builder”花竞,計(jì)算出拼接結(jié)果的length之后直接分配一個(gè)合適類型和長(zhǎng)度的SeqString作為buffer來進(jìn)行拼接劲件。而這個(gè)InternalArray里的內(nèi)容可以帶有編碼為Smi的“下一段要拼接的字符串在什么位置(position)和長(zhǎng)度(length)”信息掸哑,然后從當(dāng)前位置到下一個(gè)要拼接的位置之間填充分隔符,這樣就不會(huì)在對(duì)稀疏數(shù)組的join過程中把數(shù)組中無值的位置都填充到“string builder”的實(shí)體里去了零远。這是個(gè)run-length encoding的思路苗分。

V8還有個(gè)有趣的功能:原地縮小對(duì)象而不必為了縮小而拷貝。這個(gè)有空再具體展開寫牵辣。

=========================================

Nashorn

讓我們看看JDK8u112-b04里的Nashorn實(shí)現(xiàn)摔癣。

它比V8要簡(jiǎn)單一些,實(shí)現(xiàn)ECMAScript String值的類型都是java.lang.CharSequence接口的實(shí)現(xiàn)類,其中有:

  • 場(chǎng)景(1)(“flat string”):直接使用Java原生的 java.lang.String 類型择浊,方便用上JVM對(duì)String的優(yōu)化戴卜。在一個(gè)JDK/JVM自身就有針對(duì)1-byte / 2-byte場(chǎng)景做優(yōu)化的實(shí)現(xiàn)上(例如Oracle JDK9 / OpenJDK9的Compact Strings),Nashorn就會(huì)自動(dòng)獲得相應(yīng)的優(yōu)化琢岩;
  • 場(chǎng)景(2)(“rope”):不免俗投剥,有個(gè)實(shí)現(xiàn)了CharSequence接口的ConsString類型;
  • 場(chǎng)景(3)(“slice / substring”):直接用java.lang.String.substring()實(shí)現(xiàn)担孔,沒有額外優(yōu)化江锨。Oracle JDK / OpenJDK在JDK7后撤銷了java.lang.String的子串共享實(shí)現(xiàn),所以Nashorn里的slice() / substring()在這些JDK上會(huì)涉及拷貝開銷…orz糕篇!
  • 場(chǎng)景(4)(“intern”):只有少量地方做了intern啄育,是直接用 java.lang.String.intern() 的。
  • 場(chǎng)景(5)(外部傳入的字符串):沒有特別的對(duì)應(yīng)支持拌消。Nashorn面向的用戶是其它JVM上的語言(例如Java)挑豌,所以外部傳入的字符串最可能的也就是 java.lang.String ,正好Nashorn自身的flat string就是直接用 java.lang.String 墩崩,所以也就不用做什么額外工作來支持這些外來字符串了浮毯。

ECMAScript的String包裝對(duì)象類型則由這個(gè)NativeString類型表示:NativeString,里面就是包裝著一個(gè)代表String值的CharSequence類型引用泰鸡。

Nashorn在實(shí)現(xiàn) String.prototype.concat() 時(shí)沒有特別的實(shí)現(xiàn)债蓝,是直接把參數(shù)拼接成一串ConsString然后直接返回沒有flatten的ConsString。

=========================================

SpiderMonkey

這里用FIREFOX_AURORA_51_BASE版代碼來考察盛龄。

總體來說SpiderMonkey里的String的內(nèi)部實(shí)現(xiàn)思路與V8的非常相似饰迹。

代碼里的注釋把設(shè)計(jì)思路講解得很清楚了:

http://hg.mozilla.org/mozilla-central/file/fc69febcbf6c/js/src/vm/String.h

/*

  • JavaScript strings

  • Conceptually, a JS string is just an array of chars and a length. This array

  • of chars may or may not be null-terminated and, if it is, the null character

  • is not included in the length.

  • To improve performance of common operations, the following optimizations are

  • made which affect the engine's representation of strings:

    • The plain vanilla representation is a "flat" string which consists of a
  • string header in the GC heap and a malloc'd null terminated char array.

    • To avoid copying a substring of an existing "base" string , a "dependent"
  • string (JSDependentString) can be created which points into the base

  • string's char array.

    • To avoid O(n^2) char buffer copying, a "rope" node (JSRope) can be created
  • to represent a delayed string concatenation. Concatenation (called

  • flattening) is performed if and when a linear char array is requested. In

  • general, ropes form a binary dag whose internal nodes are JSRope string

  • headers with no associated char array and whose leaf nodes are either flat

  • or dependent strings.

    • To avoid copying the leftmost string when flattening, we may produce an
  • "extensible" string, which tracks not only its actual length but also its

  • buffer's overall size. If such an "extensible" string appears as the

  • leftmost string in a subsequent flatten, and its buffer has enough unused

  • space, we can simply flatten the rest of the ropes into its buffer,

  • leaving its text in place. We then transfer ownership of its buffer to the

  • flattened rope, and mutate the donor extensible string into a dependent

  • string referencing its original buffer.

  • (The term "extensible" does not imply that we ever 'realloc' the buffer.

  • Extensible strings may have dependent strings pointing into them, and the

  • JSAPI hands out pointers to flat strings' buffers, so resizing with

  • 'realloc' is generally not possible.)

    • To avoid allocating small char arrays, short strings can be stored inline
  • in the string header (JSInlineString). These come in two flavours:

  • JSThinInlineString, which is the same size as JSString; and

  • JSFatInlineString, which has a larger header and so can fit more chars.

    • To avoid comparing O(n) string equality comparison, strings can be
  • canonicalized to "atoms" (JSAtom) such that there is a single atom with a

  • given (length,chars).

    • To avoid copying all strings created through the JSAPI, an "external"
  • string (JSExternalString) can be created whose chars are managed by the

  • JSAPI client.

    • To avoid using two bytes per character for every string, string characters
  • are stored as Latin1 instead of TwoByte if all characters are representable

  • in Latin1.

  • Although all strings share the same basic memory layout, we can conceptually

  • arrange them into a hierarchy of operations/invariants and represent this

  • hierarchy in C++ with classes:

  • C++ type operations+fields / invariants+properties

  • ========================== =========================================

  • JSString (abstract) get(Latin1|TwoByte)CharsZ, get(Latin1|TwoByte)Chars, length / -

  • | \

  • | JSRope leftChild, rightChild / -

  • |

  • JSLinearString (abstract) latin1Chars, twoByteChars / might be null-terminated

  • | \

  • | JSDependentString base / -

  • |

  • JSFlatString - / null terminated

  • | |

  • | +-- JSExternalString - / char array memory managed by embedding

  • | |

  • | +-- JSExtensibleString tracks total buffer capacity (including current text)

  • | |

  • | +-- JSUndependedString original dependent base / -

  • | |

  • | +-- JSInlineString (abstract) - / chars stored in header

  • | |

  • | +-- JSThinInlineString - / header is normal

  • | |

  • | +-- JSFatInlineString - / header is fat

  • |

  • JSAtom - / string equality === pointer equality

  • |

  • js::PropertyName - / chars don't contain an index (uint32_t)

  • Classes marked with (abstract) above are not literally C++ Abstract Base

  • Classes (since there are no virtual functions, pure or not, in this

  • hierarchy), but have the same meaning: there are no strings with this type as

  • its most-derived type.

  • Atoms can additionally be permanent, i.e. unable to be collected, and can

  • be combined with other string types to create additional most-derived types

  • that satisfy the invariants of more than one of the abovementioned

  • most-derived types:

    • InlineAtom = JSInlineString + JSAtom (atom with inline chars, abstract)
    • ThinInlineAtom = JSThinInlineString + JSAtom (atom with inline chars)
    • FatInlineAtom = JSFatInlineString + JSAtom (atom with (more) inline chars)
  • Derived string types can be queried from ancestor types via isX() and

  • retrieved with asX() debug-only-checked casts.

  • The ensureX() operations mutate 'this' in place to effectively the type to be

  • at least X (e.g., ensureLinear will change a JSRope to be a JSFlatString).

*/

可以看到,SpiderMonkey里的 JSString 是表現(xiàn)ECMAScript String值的基類余舶。它下面的子類的層次設(shè)計(jì)跟V8的頗有相似之處啊鸭,完全應(yīng)對(duì)了本回答開頭提到的5種場(chǎng)景:

  • 場(chǎng)景(1)(“flat string”):JSFlatString 及其子類。最特別的是它的“inline string”匿值,這是在JSString的共同header里“偷空間”來存儲(chǔ)字符內(nèi)容的設(shè)計(jì)赠制。這種思路也叫做“small string”優(yōu)化,我在以前另一個(gè)回答里提及過:在stack上做small string或small vector優(yōu)化比在heap上效率高嗎? - RednaxelaFX 的回答
  • 場(chǎng)景(2)(“rope”):JSRope 實(shí)現(xiàn)了典型的二叉樹(二叉DAG)形式的rope挟憔。不過它具體用在字符串拼接的時(shí)候也有些有趣的優(yōu)化钟些,上面引用的代碼注釋以及提到了:flat string下面有一種專門為用作字符串拼接的buffer的類型JSExtensibleString,它可以在拼接過程中有一個(gè)比較長(zhǎng)的長(zhǎng)度绊谭,然后等拼接結(jié)束確定最終長(zhǎng)度后再原地把自己的長(zhǎng)度縮短到實(shí)際長(zhǎng)度政恍。這個(gè)功能也跟V8可以原地縮小對(duì)象大小的功能類似。
  • 場(chǎng)景(3)(“slice / substring”):JSDependentString
  • 場(chǎng)景(4)(“intern”):JSAtom 及其子類 js::PropertyName
  • 場(chǎng)景(5)(外部傳入的字符串):JSExternalString

上述所有涉及實(shí)際字符串內(nèi)容的存儲(chǔ)的類似都有針對(duì)7-bit Latin1與2-byte UTF-16的特化支持达传。

=========================================

Chakra / ChakraCore

請(qǐng)參考

@Thomson

大大的回答篙耗∑戎回頭有空我再寫點(diǎn)我的版本。

=========================================

其它JavaScript引擎的細(xì)節(jié)回頭再更新…

編輯于 2016-10-02

310

作者:Thomson

鏈接:https://www.zhihu.com/question/51132164/answer/124477176

來源:知乎

著作權(quán)歸作者所有宗弯。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)脯燃,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

R大已經(jīng)答全了蒙保,我就填下Chakra的坑吧曲伊。

Chakra的C++實(shí)現(xiàn)的String的基類是JavascriptString,保存的基本上就是一個(gè)字符串指針(為了跨平臺(tái)自定義了char16追他,在Windows上定義成WCHAR坟募。

ChakraCore/JavascriptString.h at master · Microsoft/ChakraCore · GitHub

class JavascriptString _ABSTRACT : public RecyclableObject

{

...

private:

const char16* m_pszValue; // Flattened, '\0' terminated contents

charcount_t m_charLength; // Length in characters, not including '\0'.

為了優(yōu)化常見使用場(chǎng)景如字符串連接,子串等操作還定義了不少子類:

JavascriptString

|- LiteralString

| |- CompundString

| |- ConcateStringBase

| |- ConcatStringN

| | |- ConcatString

| |- ConcatStringBuilder

| PropertyString

| SingleCharString

| SubString

| WritableString

比如經(jīng)常使用的字符串連接操作如下:

ChakraCore/JavascriptString.cpp at master · Microsoft/ChakraCore · GitHub邑狸,

inline JxavascriptString* JavascriptString::Concat(JavascriptString* pstLeft, JavascriptString* pstRight)

{

if(!pstLeft->IsFinalized())

{

if(CompoundString::Is(pstLeft))

{

return Concat_Compound(pstLeft, pstRight);

}

if(VirtualTableInfo<ConcatString>::HasVirtualTable(pstLeft))

{

return Concat_ConcatToCompound(pstLeft, pstRight);

}

}

else if(pstLeft->GetLength() == 0 || pstRight->GetLength() == 0)

{

return Concat_OneEmpty(pstLeft, pstRight);

}

if(pstLeft->GetLength() != 1 || pstRight->GetLength() != 1)

{

return ConcatString::New(pstLeft, pstRight);

}

return Concat_BothOneChar(pstLeft, pstRight);

}

對(duì)非簡(jiǎn)單的字符串連接直接構(gòu)造了ConcatString對(duì)象懈糯,該對(duì)象父類(ConcatStringN)里面有一個(gè)JavascriptString指針的數(shù)組(ConcatStringN通過模板可連接的JavascriptString數(shù)量參數(shù)化,ConcatString對(duì)應(yīng)最常見的N=2)单雾,在ConcatString的構(gòu)造函數(shù)里面把待連接的兩個(gè)JavascriptString存進(jìn)數(shù)組赚哗,這樣可以不用分配內(nèi)存和做copy。由于左右都是JavascriptString*硅堆,同樣可以使ConcatString屿储,這樣遞歸下去就會(huì)生成R大提到 rope 思路的DAG(我開始沒注意到這里的遞歸,多謝R大指出)渐逃。整個(gè)字符串的 flatten 是需要的時(shí)候再做够掠,借用了lazy computation的想法。

ChakraCore/ConcatString.h at master · Microsoft/ChakraCore · GitHub

template <int N>

class ConcatStringN : public ConcatStringBase

{

...

protected:

JavascriptString* m_slots[N]; // These contain the child nodes. 1 slot is per 1 item (JavascriptString*).

};

ChakraCore/ConcatString.cpp at master · Microsoft/ChakraCore · GitHub

ConcatString::ConcatString(JavascriptString* a, JavascriptString* b) :

ConcatStringN<2>(a->GetLibrary()->GetStringTypeStatic(), false)

{

a = CompoundString::GetImmutableOrScriptUnreferencedString(a);

b = CompoundString::GetImmutableOrScriptUnreferencedString(b);

m_slots[0] = a;

m_slots[1] = b;

this->SetLength(a->GetLength() + b->GetLength()); // does not include null character

}

另外對(duì)SubString也有類似的優(yōu)化茄菊,直接構(gòu)造了SubString對(duì)象作為JavascriptString的子類對(duì)象返回疯潭。

ChakraCore/SubString.h at master · Microsoft/ChakraCore · GitHub

class SubString sealed : public JavascriptString

{

void const * originalFullStringReference; // Only here to prevent recycler to free this buffer.

SubString(void const * originalFullStringReference, const char16* subString, charcount_t length, ScriptContext *scriptContext);

ChakraCore/SubString.cpp at master · Microsoft/ChakraCore · GitHub

inline SubString::SubString(void const * originalFullStringReference, const char16* subString, charcount_t length, ScriptContext *scriptContext) :

JavascriptString(scriptContext->GetLibrary()->GetStringTypeStatic())

{

this->SetBuffer(subString);

this->originalFullStringReference = originalFullStringReference;

this->SetLength(length);

...

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市面殖,隨后出現(xiàn)的幾起案子竖哩,更是在濱河造成了極大的恐慌,老刑警劉巖脊僚,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件相叁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡辽幌,警方通過查閱死者的電腦和手機(jī)增淹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來舶衬,“玉大人埠通,你說我怎么就攤上這事」溆蹋” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)虽画。 經(jīng)常有香客問我舞蔽,道長(zhǎng),這世上最難降的妖魔是什么码撰? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任渗柿,我火速辦了婚禮,結(jié)果婚禮上脖岛,老公的妹妹穿的比我還像新娘朵栖。我一直安慰自己,他們只是感情好柴梆,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布陨溅。 她就那樣靜靜地躺著,像睡著了一般绍在。 火紅的嫁衣襯著肌膚如雪门扇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天偿渡,我揣著相機(jī)與錄音臼寄,去河邊找鬼。 笑死溜宽,一個(gè)胖子當(dāng)著我的面吹牛吉拳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播适揉,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼合武,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了涡扼?” 一聲冷哼從身側(cè)響起稼跳,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吃沪,沒想到半個(gè)月后汤善,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡票彪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年红淡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片降铸。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡在旱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出推掸,到底是詐尸還是另有隱情桶蝎,我是刑警寧澤驻仅,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站登渣,受9級(jí)特大地震影響噪服,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜胜茧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一粘优、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧呻顽,春花似錦雹顺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至昧碉,卻和暖如春英染,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背被饿。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工四康, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人狭握。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓闪金,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親论颅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子哎垦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容

  • Lua 5.1 參考手冊(cè) by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,836評(píng)論 0 38
  • package cn.itcast_01;/* 字符串:就是由多個(gè)字符組成的一串?dāng)?shù)據(jù)。也可以看成是一個(gè)字符數(shù)組恃疯。 ...
    蛋炒飯_By閱讀 590評(píng)論 0 0
  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗(yàn)漏设。 張土汪:刷leetcod...
    土汪閱讀 12,748評(píng)論 0 33
  • 一、字符串在C#中今妄,字符串是一系列不可修改的Unicode字符郑口,創(chuàng)建字符串后,就不能修改它盾鳞。要?jiǎng)?chuàng)建字符串犬性,最常用的...
    CarlDonitz閱讀 1,287評(píng)論 0 2
  • 發(fā)哥是我一起實(shí)習(xí)的好哥們,我兩同一天上的粵電1腾仅,是同期的實(shí)習(xí)生乒裆。發(fā)哥姓陳名一發(fā),一發(fā)不可收拾的一發(fā)推励。后來才知道鹤耍,這...
    ab的日記閱讀 1,706評(píng)論 1 8