Racket中字节字符串与字符串的字符内存占用对比及计算方法
Racket字节字符串与字符串的内存占用差异及计算方法
内存占用差异
- 字节字符串(
bytes类型):每个元素是8位无符号字节(取值范围0-255),单个元素直接占用1字节内存。字节字符串仅能存储ASCII字符或原始二进制数据,无额外编码开销。 - 字符串(
string类型):每个元素是Unicode标量值,支持所有Unicode字符。其内存占用分为两部分:- 对象头部开销:包含类型标识、长度等元数据,固定约16字节(不同Racket版本可能略有差异);
- 字符存储开销:
- ASCII字符(U+0000至U+007F):每个占用1字节;
- 基本多语言平面(BMP)非ASCII字符(U+0080至U+FFFF):每个占用2-3字节(取决于底层UTF-8/UTF-16编码实现);
- 超出BMP的字符(如Emoji,U+10000及以上):以代理对形式存储,每个占用4字节。
内存占用计算方法
Racket内置了object-size函数(需导入racket/object库),可直接获取对象的总内存占用。结合对象长度,可计算出单个元素的实际占用:
示例代码
(require racket/object) ;; 计算字节字符串内存占用 (define bstr #"hello") (displayln (format "字节字符串总大小: ~a 字节" (object-size bstr))) (displayln (format "单元素平均占用: ~a 字节" (/ (- (object-size bstr) (object-size #"")) (bytes-length bstr)))) ;; 计算ASCII字符串内存占用 (define str-ascii "hello") (displayln (format "ASCII字符串总大小: ~a 字节" (object-size str-ascii))) (displayln (format "单字符平均占用: ~a 字节" (/ (- (object-size str-ascii) (object-size "")) (string-length str-ascii)))) ;; 计算非ASCII字符串内存占用 (define str-unicode "你好🌍") (displayln (format "Unicode字符串总大小: ~a 字节" (object-size str-unicode))) (displayln (format "单字符平均占用: ~a 字节" (/ (- (object-size str-unicode) (object-size "")) (string-length str-unicode))))
说明
- 通过
(object-size #"")和(object-size "")可获取字节字符串/字符串的固定头部开销,避免硬编码数值; - 字符串的实际字符存储开销由其包含的Unicode字符范围决定,多字节字符会直接增加总内存占用。
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

