先推荐两篇文章:
http://www.wagerlabs.com/blog/2008/02/parsing-text-an.html
http://ppolv.wordpress.com/2008/02/25/parsing-csv-in-erlang/
(都需要爬墙访问,该死的‘功夫网’)
Erlang中解析文本协议,使用Binary无疑是高效的选择,但是我发现,文章中,对Binary中各个字节组合为字符串,都是使用list的:
NewList = lists:reverse([Char|OldList])
而不是
NewList = binary_to_list(<<OldBin/binary,$Char>>)
稍后我做了个测试,证明了对于大量短字符串的构成,比如将 <<"GET /index.html HTTP/1.1">> 解析为 ["GET","/index.html","HTTP/1.1"],使用list会更好一些。
简单写了个循环的测试代码:
test_append() ->
test_char_append(100),
test_char_append(1000),
test_char_append(10000),
test_char_append(100000),
test_char_append(1000000),
test_char_append(10000000),
test_field_append(10000),
test_field_append(100000),
test_field_append(200000),
test_field_append(300000).
test_char_append(Loop) ->
erlang:statistics(wall_clock),
test_char_append_by_list(Loop, []),
{_,T1} = erlang:statistics(wall_clock),
test_char_append_by_binary(Loop, <<>>),
{_,T2} = erlang:statistics(wall_clock),
io:format("~p loops, test_char_append_by_list using time: ~pms~n", [Loop,T1]),
io:format("~p loops, test_char_append_by_binary using time: ~pms~n~n", [Loop,T2]),
ok.
test_field_append(Loop) ->
erlang:statistics(wall_clock),
test_field_append_by_list(Loop, []),
{_,T1} = erlang:statistics(wall_clock),
test_field_append_by_binary(Loop, []),
{_,T2} = erlang:statistics(wall_clock),
io:format("~p loops, test_field_append_by_list using time: ~pms~n", [Loop,T1]),
io:format("~p loops, test_field_append_by_binary using time: ~pms~n~n", [Loop,T2]),
ok.
test_char_append_by_list(0, List) -> lists:reverse(List);
test_char_append_by_list(N, List) -> test_char_append_by_list(N-1, [$!|List]).
test_char_append_by_binary(0, Bin) -> binary_to_list(Bin);
test_char_append_by_binary(N, Bin) -> test_char_append_by_binary(N-1, <<Bin/binary, $!>>).
test_field_append_by_list(0, List) -> lists:reverse(List);
test_field_append_by_list(N, List) ->
Field = test_char_append_by_list(100, []),
test_field_append_by_list(N-1, [Field|List]).
test_field_append_by_binary(0, List) -> lists:reverse(List);
test_field_append_by_binary(N, List) ->
Field = test_char_append_by_binary(100, <<>>),
test_field_append_by_binary(N-1, [Field|List]).
输出大致如下:
引用
100 loops, test_char_append_by_list using time: 0ms
100 loops, test_char_append_by_binary using time: 0ms
1000 loops, test_char_append_by_list using time: 0ms
1000 loops, test_char_append_by_binary using time: 0ms
10000 loops, test_char_append_by_list using time: 0ms
10000 loops, test_char_append_by_binary using time: 0ms
100000 loops, test_char_append_by_list using time: 16ms
100000 loops, test_char_append_by_binary using time: 16ms
1000000 loops, test_char_append_by_list using time: 203ms
1000000 loops, test_char_append_by_binary using time: 156ms
10000000 loops, test_char_append_by_list using time: 2922ms
10000000 loops, test_char_append_by_binary using time: 1594ms
10000 loops, test_field_append_by_list using time: 62ms
10000 loops, test_field_append_by_binary using time: 172ms
100000 loops, test_field_append_by_list using time: 1109ms
100000 loops, test_field_append_by_binary using time: 1860ms
200000 loops, test_field_append_by_list using time: 2672ms
200000 loops, test_field_append_by_binary using time: 4937ms
300000 loops, test_field_append_by_list using time: 3438ms
300000 loops, test_field_append_by_binary using time: 7062ms
可见当字符串较短时,使用list比binary速度更佳,当字符串达到10w以上(谁没事搞那么长的list?),binary才有一点点的优势。在大量构造短字符串时,还是乖乖用list组合并反转吧
分享到:
相关推荐
7. **字符串性能**:由于字符串不可变,频繁的修改操作(如拼接)可能导致效率问题。在某些情况下,使用字符串缓冲区或列表操作后再转换为字符串能提高性能。 8. **字符串比较**:根据编程语言,字符串比较可能是...
"串的堆分配存储方法"是指在处理大量字符串时,为提高内存利用率和操作效率,使用堆内存来动态分配和管理字符串存储空间的一种策略。这种方法通常与C++等语言中的自定义数据结构相结合,例如这里的"HString"类,它...
5. 静态String类:C#的`System.String`类包含大量静态方法,如`Concat`连接字符串,`Compare`比较字符串,`ToLower`和`ToUpper`转换大小写等。 二、正则表达式 1. 正则表达式基础:正则表达式是一种模式匹配工具,...
Java中提供了两种主要的字符串比较方法:`equals()` 和 `equalsIgnoreCase()`。`equals()` 方法用于比较两个字符串的字符序列是否相同,它不考虑字符的大小写。而 `equalsIgnoreCase()` 方法在比较时忽略字符的大小...
本课程设计的主题聚焦在C语言和C++实现的字符串模式匹配,主要探讨了两种算法:KMP算法和朴素算法。 首先,让我们了解一下朴素算法。朴素算法是最直观的字符串匹配方法,它通过从文本串的起始位置开始,逐个字符地...
在IT领域,字符比较是常见的操作,特别是在文本处理和字符串分析中。本项目"两字符比较-纯C#版本-vs2010编写.rar"提供了一个C#实现的解决方案,用于对比两段英文文本的相似性,适用于任意长度的句子。这种功能在抄袭...
6. **比较操作**:顺序串的比较可以按照字符顺序逐个比较,用于实现字符串的排序或者判断两个字符串是否相等。 7. **连接操作**:将两个顺序串合并成一个新的顺序串,需要创建一个新的数组,将两个串的字符依次添加...
`std::string` 和 `std::wstring` 是两种不同的字符串类型,分别用于处理单字节和宽字符。 **1.6.1 简介** `std::wstring` 是一个处理宽字符字符串的类,通常用于 Unicode 字符串。 **1.6.2 `std::wstring` 实例*...
测试用例通过函数和类两种方式来逐个读取大字符串中的字符,以此来比较这三种语言在执行效率上的优劣。 首先,让我们看下Node.js的实现。Node.js使用了内置的`fs`模块来读取文件内容,并且提供了同步读取(`...
在Golang中进行字符串处理时,选择合适的构造方式对于提升程序性能至关重要。本节将探讨不同字符串连接方法及其性能表现。 ##### Fmt VS "+" 使用`fmt.Sprintf`或`fmt.Printf`等函数与使用`+`操作符来拼接字符串是...
"刁肥宅制作的BF、KMP与BM测试用数据"提供了一组特殊的测试集,这些数据是由大小写字母和数字组成的随机字符串,规模从10到10^9不等。这种规模的字符串可以用来测试不同算法在处理大规模数据时的性能。测试数据的...
这通常涉及两种基本类型的问题:确定子串是否存在于主串中,以及如果存在,找出所有出现的位置。 在字符串匹配中,有许多经典的算法,例如: 1. **Brute Force**(暴力匹配):也称为朴素字符串匹配,是最基础的...
在这个文件中,我们可能会看到各种测试用例,检查UTF-8字符串类的构造、赋值、比较、截断、插入、删除、转换等操作是否符合预期。测试通常会覆盖边界条件,如空字符串、单字节字符、多字节字符、非法UTF-8序列等。 ...
文档中展示了两种常见的StringBuilder的构造方法: - 使用带字符序列的构造函数:`StringBuilder sb = new StringBuilder("HelloWorld!");` 创建一个值为"HelloWorld!"的StringBuilder对象。 - 使用带字符序列和初始...
4.1.4 字符数组和字符串处理 147 4.1.5 多维数组 150 4.2 间接数据存取 153 4.2.1 指针的概念 153 4.2.2 声明指针 154 4.2.3 使用指针 155 4.2.4 初始化指针 157 4.2.5 sizeof运算符 162 4.2.6 ...
在提供的测试示例中,比较了`eval`和`new Function()`这两种方式解析大型JSON字符串的性能。结果显示,`new Function()`方法比`eval`快了数百倍,这再次证明了其在处理JSON解析时的高效性。通常,`eval`应避免用于...
在"for foreach效率测试代码"中,我们看到的是对这两种循环方式进行性能比较,执行1000000万次字符串遍历操作。这种测试通常是为了评估在大量数据处理时,哪种循环方式更高效。 在大多数情况下,`foreach`循环看...
在这个SUBLEX问题中,提供了两种更新方式:计数排序(Counting Sort)和深度优先搜索(DFS)。计数排序是一种非基于比较的排序算法,适用于整数排序,它的主要思想是对每一个输入元素x,确定小于x的元素个数,然后...