Lua中使用table.concat连接大量字符串实例

最近2天都没有写新的文章了,主要是最近的内容没有特别有意思的。

之前的协同程序也暂时没有感觉到特别适用的地方,今天在看数据结构的部分,也是没多大意思(不代表没用)。

但是突然发现了一个有意思的地方,那就是——连接大量字符串的时候,如何解决效率问题。

1.预备知识,在Lua中获取系统时间

为了直观地看到效率的差别,我们要计算一下代码的执行时间,所以,先来看看如何计算吧:

代码如下:

local startTime = os.clock();
    for i = 1, 1990000000, 1 do
      
    end
  
    local endTime = os.clock();
    local useTime = endTime - startTime;
    print("消耗时间:" .. useTime .. "s");

输出结果如下:

代码如下:

[LUA-print] 消耗时间:0.59699999999998s

os.clock()可以获得当前系统时间(单位:秒),只要在代码执行前后都获取一次时间,取差值,就能得到代码执行的时间消耗了。

2.Lua中连接大量字符串

我们来试试连接一大堆字符串吧,如下代码:

代码如下:

local strs = {};
    for i = 1, 30000, 1 do
        strs[i] = "helloworld";
    end
  
    local result = "";
  
    local startTime = os.clock();
    for index, str in ipairs(strs) do
        result = result .. str;
    end
  
    local endTime = os.clock();
    local useTime = endTime - startTime;
  
    print("消耗时间:" .. useTime .. "s");

首先,创建了一个strs的table,里面存放30000个字符串,虽然内容都是相同的,但确实是有30000个字符串在里面。

然后,使用一个result变量,把strs里的所有字符串用连接操作符连接起来~
 
咋一看,没什么问题吧,很正常吖。(小若:别开玩笑了,你会不挖坑给我们踩?)
运行一下,输出结果如下:

代码如下:

[LUA-print] 消耗时间:1.667s

才消耗了1.667s,还好吧,完全能接受,呵呵。(小若:快说,别卖关子!)

啊,怎么可能啊!我们可是闲得X疼的人,怎么可能忍受3万次循环就耗去1秒多的时间呢?

你让那些做算法的人怎么办,他们肯定无法接受的!

3.使用table.concat快速连接大量字符串

所以了,就有了table.concat,concat函数对字符串连接进行了优化,即使进行大量的连接操作,也不会消耗多少时间。
来试试吧,如下代码:

代码如下:

local strs = {};
    for i = 1, 30000, 1 do
        strs[i] = "helloworld";
    end
  
    local result = "";
  
    local startTime = os.clock();
    result = table.concat(strs);
  
    local endTime = os.clock();
    local useTime = endTime - startTime;
  
    print("消耗时间:" .. useTime .. "s");

立刻来看输出结果:

代码如下:

[LUA-print] 消耗时间:0.0049999999998818s

怎么样?这差别,简直就没法形容了。

4.结束

Lua的字符串和Java的字符串差不多,都是不可变的,不可变的意思是什么呢?

比如刚刚的result字符串,每一次进行连接操作之后,其实就产生了新的字符串,不再是原来的那个了。

于是,不断连接,就不断产生新的字符串,产生新字符串是需要复制操作,随着连接操作的不断进行着,字符串越来越大,复制操作也就越来越耗时。

这就是为什么,简单地进行连接操作会这么慢了。
 
好了,就说这么多喇~

(0)

相关推荐

  • Lua字符串库中的几个重点函数介绍

    在<Lua中的一些库>中也说到了,要对string库的模式匹配进行单独的讲解.对于字符串的处理,对于任何语言的学习来说,都是一个难点,而且也是一个必会的知识点.给你一个字符串,让你按照某种需求进行处理,你不会,那是多么尴尬的一件事情.所以,看完<Lua中的一些库>和这篇文章之后,我争取做到让你在处理字符串时,不再感到捉襟见肘,不再尴尬. 说到Lua中的模式匹配,基本上就是围绕着以下几个函数展开的: 1.find: 2.match: 3.gsub: 4.gmatch. 我的总结也就是

  • Lua字符串模式匹配函数小结

    模式匹配函数 在string库中功能最强大的函数是: 复制代码 代码如下: string.find(字符串查找) string.gsub(全局字符串替换) string.gfind(全局字符串查找) string.gmatch(返回查找到字符串的迭代器) 这些函数都是基于模式匹配的.与其他脚本语言不同的是,Lua并不使用POSIX规范的正则表达式[4](也写作regexp)来进行模式匹配.主要的原因出于程序大小方面的考虑:实现一个典型的符合POSIX标准的regexp大概需要4000行代码,这比

  • Lua源码中字符串类型的实现

    概述 Lua完全采用8位编码,Lua字符串中的字符可以具有任何数值编码,包括数值0.也就是说,可以将任意二进制数据存储到一个字符串中.Lua的字符串是不可变的值(immutable values).如果修改,实质上是新建一个字符串.根据上文<Lua中数据类型的源码实现>中知道,在Lua中,字符串是自动内存管理机制所管理的对象,并且由联合体TString来实现存储字符串值的.下面将通过Lua 5.2.1的源码来看字符串的实现以及总结了在Lua中使用字符串的注意事项. 源码实现 首先来看字符串对应

  • Lua函数与字符串处理简明总结

    函数的定义是以function关键字开始的,后面函数的名称,然后是要传递给函数的参数,如果没有参数传给函数,仍然需要用()来表示一个空的参数列表,以end关键字结尾. 复制代码 代码如下: function 函数名()  ...  ...  ... end 1. 单一参数 复制代码 代码如下: function F_1(var)  print("My website is: "  var) end 参数var传递给了函数,并在函数中使用,同时,函数中的参数是局部变量,在函数调用结束后被

  • 使用lua实现split字符串分隔

    LUA并不象其它许多"大而全"的语言那样,包括很多功能,比如网络通讯.图形界面等.但是LUA可以很容易地被扩展:由宿主语言(通常是C或C++)提供这些功能,LUA可以使用它们,就像是本来就内置的功能一样.LUA只包括一个精简的核心和最基本的库.这使得LUA体积小.启动速度快,从而适合嵌入在别的程序里.因此在lua中并没有其他语言那样多的系统函数.习惯了其他语言的字符串分割函数,与是就自己写了一个,记录在此,以备使用. 下面在简单介绍下lua: Lua 是一个小巧的脚本语言.作者是巴西人

  • Lua中的string库(字符串函数库)总结

    Lua解释器对字符串的支持很有限.一个程序可以创建字符串并连接字符串,但不能截取子串,检查字符串的大小,检测字符串的内容.在Lua中操纵字符串的功能基本来自于string库. 字符串库中的一些函数是非常简单的: string.len(s)          返回字符串s的长度: string.rep(s, n)      返回重复n次字符串s的串:你使用string.rep("a", 2^20)可以创建一个1M bytes的字符串(比如,为了测试需要): string.lower(s)

  • Lua字符串库(string库)学习笔记

    Lua 最强大的特性之一就是它的字符串处理能力,它支持字符格式化输出,具有可扩展的模式匹配查找功能,以及一些实用的字符操作,例如查询.截取.替换和删除等字符串操作,这些字符串操作函数都封装在一个名为 string 的模块里. Lua 里的字符索引是从 1 开始,索引值也可以是负数,这种情况将被解释成向后索引,从字符串末尾开始算起. 下面是 Lua 5.2 提供的字符串操作函数: byte 函数 string.byte 把字符串里的第 i 个字符转为 ASCII编码,默认是输出第一个字符的编码(只

  • Lua教程(五):C/C++操作Lua数组和字符串示例

    本文将介绍如何在C/C++里面操作Lua的数组和字符串类型,同时还会介绍如何在C/C++函数里面存储Lua状态(registry和upvalue),而registry在使用C/C++自定义类型时非常有用,可以方便地为userdata指定metatable. C/C++操作Lua数组 Lua数组Overview 在Lua里面,数组只不过是key为整数的table而已.比如一个table为array = {12,"Hello", "World"},它是一个数组,可以用下

  • Lua中字符串(string)浅析

    Lua中字符串可以使用""或''声明,类似Javascript中的用法. 复制代码 代码如下: > ="sdfdsf" sdfdsf > ='sfdd' sfdd > ='abc"' abc" > ="abc'" abc' 同Java.Python一样,Lua的字符串是不可修改的值,可以通过string.gsub函数来替换字符串中的子串: 复制代码 代码如下: > s = string.gsub(

  • Lua中使用table.concat连接大量字符串实例

    最近2天都没有写新的文章了,主要是最近的内容没有特别有意思的. 之前的协同程序也暂时没有感觉到特别适用的地方,今天在看数据结构的部分,也是没多大意思(不代表没用). 但是突然发现了一个有意思的地方,那就是--连接大量字符串的时候,如何解决效率问题. 1.预备知识,在Lua中获取系统时间 为了直观地看到效率的差别,我们要计算一下代码的执行时间,所以,先来看看如何计算吧: 复制代码 代码如下: local startTime = os.clock();     for i = 1, 19900000

  • Lua中使用table实现的其它5种数据结构

    lua中的table不是一种简单的数据结构,它可以作为其他数据结构的基础,如:数组,记录,链表,队列等都可以用它来表示. 1.数组 在lua中,table的索引可以有很多种表示方式.如果用整数来表示table的索引,即可用table来实现数组,在lua中索引通常都会从1开始. 复制代码 代码如下: --二维数组 n=10 m=10 arr={} for i=1,n do      arr[i]={}    for j=1,m do       arr[i][j]=i*j    end end f

  • Lua中的table浅析

    Lua的table提供了Map的功能,实现了"关联数组",并且整数.字符串甚至nil都可以作为索引/key:table没有固定的大小.   基于table,可以表示普通数组.符号表.集合.记录.队列和其他数据结构.   而Lua也是通过table来解决模块(module).包(package)和对象(Object)的. 例如io.read表示使用"read"来索引table io.   在Lua中,table既不是值也不是"变量",而是对象,可以

  • Java中BufferedReader类获取输入输入字符串实例

    使用Scanner来取得使用者的输入很方便,但是它以空白来区隔每一个输入字符串,在某些时候并不适用,因为使用者可能输入一个字符串,中间会包括空白字元,而您希望取得完整的字符串. 您可以使用BufferedReader类别,它是java.io包中所提供的一个类,所以使用这个类时必须先import java.io包:使用BufferedReader对象的readLine()方法必须处理IOException异常(exception),异常处理机制是Java提供给程序设计人员捕捉程序中可能发生的错误所

  • Lua中的table学习笔记

    table 在 Lua 里是一种重要的数据结构,它可以说是其他数据结构的基础,通常的数组.记录.线性表.队列.集合等数据结构都可以用 table 来表示,甚至连全局变量(_G).模块.元表(metatable)等这些重要的 Lua 元素都是 table 的结构.可以说,table  是一个强大而又神奇的东西. table 特性 在之前介绍 Lua 数据类型时,也说过了 table 的一些特性,简单列举如下(详情可查看之前的介绍): 1.table是一个"关联数组",数组的索引可以是数字

  • Lua中对table排序实例

    lua中利用到的排序的基本上就是构造函数(table)了,为了便于和C区分开来,我俗称它为表单. 实例:(原理就是LUA集成的冒泡算法) 排序的一般姿势(对于只包含数字或者只包含字符串的简单数组) 复制代码 代码如下: table.sort(test) 扩展版 复制代码 代码如下: table.sort(test, function(a,b) return a.id<b.id end ) 实例一:值排序 1.数组模式 复制代码 代码如下: local test0 ={1,9,2,8,3,7,4,

  • Lua中获取table长度的方法

    官方文档是这么描述#的: 取长度操作符写作一元操作 #. 字符串的长度是它的字节数(就是以一个字符一个字节计算的字符串长度). table t 的长度被定义成一个整数下标 n . 它满足 t[n] 不是 nil 而 t[n+1] 为 nil: 此外,如果 t[1] 为 nil ,n 就可能是零. 对于常规的数组,里面从 1 到 n 放着一些非空的值的时候, 它的长度就精确的为 n,即最后一个值的下标. 如果数组有一个"空洞" (就是说,nil 值被夹在非空值之间), 那么 #t 可能是

  • Lua中设置table为只读属性的方法详解

    项目中部分只读表易被人误改写,故决定在非线上环境里对这些表附加只读属性,方便在出现误改写的时候抛出lua错误,最终版代码如下: --[[------------------------------------------------------------------------------ -** 设置table只读 出现改写会抛出lua error -- 用法 local cfg_proxy = read_only(cfg) retur cfg_proxy -- 增加了防重置设置read_o

  • 举例讲解Lua中的Table数据结构

    文中-- 两个横线开始单行的注释,--[[加上两个[和]表示多行的注释--]]. 复制代码 代码如下: -- Table = Lua唯一的数据结构; --         它们是关联数组. -- 类似于PHP的数组或者js的对象, -- 它们是哈希查找表(dict),也可以按list去使用. 复制代码 代码如下: -- 按字典/map的方式使用Table: -- Dict的迭代默认使用string类型的key: t = {key1 = 'value1', key2 = false} 复制代码 代

  • Lua中获取table长度问题探讨

    又有同事在lua的table长度问题上犯错了,我们一起来看看吧~~~ 看以下代码: 复制代码 代码如下: local tblTest1 =  {      1,      2,      3  }    print(table.getn(tblTest1)) 这段代码输出的结果是3,这个大家都知道,是吧.不管最后那个3后面有没有加逗号,结果都是3. 再看下面的代码: 复制代码 代码如下: local tblTest2 =  {      1,      a = 2,      3,  }   

随机推荐