代码之家  ›  专栏  ›  技术社区  ›  okoman

Lua-当前时间(毫秒)

  •  65
  • okoman  · 技术社区  · 17 年前

    是否有一种以毫秒或毫秒为单位获取当前时间的通用方法?

    有 os.time() ,但它只提供完整的秒数。

    9 回复  |  直到 9 年前
        1
  •  63
  •   waqas    17 年前

    我使用LuaSocket来获得更高的精度。

    require "socket"
    print("Milliseconds: " .. socket.gettime()*1000)
    

    这当然增加了依赖性,但对于个人使用(例如,在基准测试脚本中)效果很好。

        2
  •  59
  •   Valerio Schiavoni    16 年前

    local x = os.clock()
    local s = 0
    for i=1,100000 do s = s + i end
    print(string.format("elapsed time: %.2f\n", os.clock() - x))
    
        3
  •  36
  •   Kevlar    17 年前

    在标准C lua中,没有。除非您愿意自己修改lua解释器,让os.time使用您想要的分辨率,否则您必须满足秒数。但是,如果您编写代码让其他人自己运行,而不是像web应用程序那样完全控制环境,那么这可能是不可接受的。

    编辑:另一个选择是用C编写自己的小型DLL,用一个新函数扩展lua,该函数将为您提供所需的值,并要求DLL与您的代码一起分发给使用它的任何人。

        4
  •  18
  •   Jujhar Singh    7 年前

    操作系统时间()

    os.time()
    return sec // only
    

    posix.时钟获取时间(clk)

    https://luaposix.github.io/luaposix/modules/posix.time.html#clock_gettime

    require'posix'.clock_gettime(0)
    return sec, nsec
    

    linux/time.h// man clock_gettime

    /*
     * The IDs of the various system clocks (for POSIX.1b interval timers):
     */
    #define CLOCK_REALTIME                  0
    #define CLOCK_MONOTONIC                 1
    #define CLOCK_PROCESS_CPUTIME_ID        2
    #define CLOCK_THREAD_CPUTIME_ID         3
    #define CLOCK_MONOTONIC_RAW             4
    #define CLOCK_REALTIME_COARSE           5
    #define CLOCK_MONOTONIC_COARSE          6
    

    http://w3.impa.br/~diego/software/luasocket/socket.html#gettime

    require'socket'.gettime()
    return sec.xxx
    

    waqas 说


    比较,;测验

    获取μ毫秒。lua

    local posix=require'posix'
    local socket=require'socket'
    
    for i=1,3 do
        print( os.time() )
        print( posix.clock_gettime(0) )
        print( socket.gettime() )
        print''
        posix.nanosleep(0, 1) -- sec, nsec
    end
    

    lua get_millisecond.lua
    1490186718
    1490186718      268570540
    1490186718.2686
    
    1490186718
    1490186718      268662191
    1490186718.2687
    
    1490186718
    1490186718      268782765
    1490186718.2688
    
        5
  •  10
  •   Cody Duncan    14 年前

    我为Windows上的lua制作了一个合适的解决方案。我基本上按照Kevlar的建议做了,但是使用了一个共享库而不是DLL。这已经使用cygwin进行了测试。

    我编写了一些与lua兼容的C代码,将其编译到一个共享库(.so文件通过cygwin中的gcc),然后使用package.cpath和require“”将其加载到lua中。为方便起见,编写了一个适配器脚本。以下是所有来源:

    ////////////////////////////////////////////////////////////////
    //HighResTimer.c by Cody Duncan
    //
    //compile with:  gcc -o Timer.so -shared HighResTimer.c -llua5.1
    //compiled in cygwin after installing lua (cant remember if I 
    //   installed via setup or if I downloaded and compiled lua, 
    //   probably the former)
    ////////////////////////////////////////////////////////////////
    #include <windows.h>
    
    typedef unsigned __int64 u64;
    double mNanoSecondsPerCount;
    
    #include "lua.h"
    #include "lualib.h"
    #include "lauxlib.h"
    
    
    int prevInit = 0;
    int currInit = 0;
    u64 prevTime = 0;
    u64 currTime = 0;
    u64 FrequencyCountPerSec;
    
    LARGE_INTEGER frequencyTemp;
    static int readHiResTimerFrequency(lua_State *L)
    {
        QueryPerformanceFrequency(&frequencyTemp);
        FrequencyCountPerSec = frequencyTemp.QuadPart;
        lua_pushnumber(L, frequencyTemp.QuadPart);
        return 1;
    }
    
    LARGE_INTEGER timerTemp;
    static int storeTime(lua_State *L)
    {
        QueryPerformanceCounter(&timerTemp);
    
        if(!prevInit)
        {
            prevInit = 1;
            prevTime = timerTemp.QuadPart;
        }
        else if (!currInit)
        {
            currInit = 1;
            currTime = timerTemp.QuadPart;
        }
        else
        {
            prevTime = currTime;
            currTime = timerTemp.QuadPart;
        }
    
        lua_pushnumber(L, timerTemp.QuadPart);
        return 1;
    }
    
    static int getNanoElapsed(lua_State *L)
    {
        double mNanoSecondsPerCount = 1000000000/(double)FrequencyCountPerSec;
        double elapsedNano = (currTime - prevTime)*mNanoSecondsPerCount;
        lua_pushnumber(L, elapsedNano);
        return 1;
    }
    
    
    int luaopen_HighResolutionTimer (lua_State *L) {
    
        static const luaL_reg mylib [] = 
        {
            {"readHiResTimerFrequency", readHiResTimerFrequency},
            {"storeTime", storeTime},
            {"getNanoElapsed", getNanoElapsed},
            {NULL, NULL}  /* sentinel */
        };
    
        luaL_register(L,"timer",mylib);
    
        return 1;
    }
    

    --

    现在让我们将其加载到lua脚本HighResTimer.lua中。

    #!/bin/lua
    ------------------------------------
    ---HighResTimer.lua by Cody Duncan
    ---Wraps the High Resolution Timer Functions in
    ---   Timer.so
    ------------------------------------
    
    package.cpath = "./Timer.so"     --assuming Timer.so is in the same directory
    require "HighResolutionTimer"    --load up the module
    timer.readHiResTimerFrequency(); --stores the tickFrequency
    
    
    --call this before code that is being measured for execution time
    function start()
        timer.storeTime();
    end
    
    --call this after code that is being measured for execution time
    function stop()
        timer.storeTime();
    end
    
    --once the prior two functions have been called, call this to get the 
    --time elapsed between them in nanoseconds
    function getNanosElapsed()
        return timer.getNanoElapsed();
    end
    

    --

    最后,利用定时器TimerTest.lua。

    #!/bin/lua
    ------------------------------------
    ---TimerTest.lua by Cody Duncan
    ---
    ---HighResTimer.lua and Timer.so must 
    ---   be in the same directory as 
    ---   this script.
    ------------------------------------
    
    require './HighResTimer' 
    
    start();
    for i = 0, 3000000 do io.write("") end --do essentially nothing 3million times.
    stop();
    
    --divide nanoseconds by 1 million to get milliseconds
    executionTime = getNanosElapsed()/1000000; 
    io.write("execution time: ", executionTime, "ms\n");
    

        6
  •  4
  •   deepskyblue86    11 年前

    如果您在nginx/openresty中使用lua,您可以使用 ngx.now() 返回精度为毫秒的浮点值

        7
  •  3
  •   Pierz    6 年前

    ngx.now() 作用尽管如果您希望获得细粒度毫秒精度,可能需要首先调用ngx.update_time()。或者如果你想更进一步。。。

    luajit 启用环境,如OpenResty,则还可以使用 ffi 要访问基于C的时间函数,例如 gettimeofday() e、 g:(注:附件) pcall 检查是否存在 struct timeval 仅当您反复运行时才需要,例如通过 content_by_lua_file 在OpenResty中,如果没有它,您会遇到如下错误 attempt to redefine 'timeval'

    if pcall(ffi.typeof, "struct timeval") then
            -- check if already defined.
    else
            -- undefined! let's define it!
            ffi.cdef[[
               typedef struct timeval {
                    long tv_sec;
                    long tv_usec;
               } timeval;
    
            int gettimeofday(struct timeval* t, void* tzp);
    ]]
    end
    local gettimeofday_struct = ffi.new("struct timeval")
    local function gettimeofday()
            ffi.C.gettimeofday(gettimeofday_struct, nil)
            return tonumber(gettimeofday_struct.tv_sec) * 1000000 + tonumber(gettimeofday_struct.tv_usec)
    end
    

    然后是新的lua 函数可以从lua调用,以向用户提供时钟时间

    事实上,我们也可以采取类似的做法 clock_gettime() 取得 纳秒

        8
  •  2
  •   Doug Currie    17 年前

    凯夫拉尔是正确的。

    自定义DLL的替代方法是 Lua Alien

        9
  •  2
  •   smartius    10 年前

    在openresty中有一个函数 ngx.req.start_time

    从文档中:

    返回一个浮点数,表示创建当前请求时的时间戳(包括毫秒作为小数部分)。

        10
  •  0
  •   qwer    17 年前

    您可以使用C函数gettimeofday: http://www.opengroup.org/onlinepubs/000095399/functions/gettimeofday.html

    在这里,C库'ul_time',函数sec_usec驻留在'time'全局表中,并返回秒,useconds。将DLL复制到Lua文件夹,用“ul_time”打开它。

    http://depositfiles.com/files/3g2fx7dij

        11
  •  0
  •   Stuart P. Bentley    5 年前

    如果您所在的系统具有与GNU兼容的 date 您可以执行以下命令,以毫秒为单位获取历元时间:

    local function gethammertime()
      return tonumber(assert(assert(io.popen'date +%s%3N'):read'a'))
    end
    

    请注意 assert 日期 将分别传播错误。还请注意,这依赖于垃圾收集(或Lua5.4中的终结器)来关闭进程句柄:如果使用Lua的5.4之前版本和资源耗尽是一个问题,您可能希望将其扩展到三行,如 Klesun's Windows-based answer 并显式关闭句柄。

        12
  •  0
  •   Klesun Gian Marco    5 年前

    如果您的环境是Windows,并且您可以访问系统命令,则可以使用 io.popen(command)

    local handle = io.popen("echo %time%")
    local result = handle:read("*a")
    handle:close()
    

    结果将保存字符串 hh:mm:ss.cc 格式:(带尾随换行符)

    "19:56:53.90\n"
    

    注意,它位于本地时区,所以您可能只想提取 .cc os.time() .