Lua - 以毫秒为单位的当前时间

时间:2009-01-20 21:03:34

标签: time lua

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

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

11 个答案:

答案 0 :(得分:57)

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

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

这当然会增加依赖性,但适合个人使用(例如在基准测试脚本中)。

答案 1 :(得分:52)

如果您想要进行基准测试,可以使用doc.clock所示的os.clock:

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))

答案 2 :(得分:33)

在标准C lua中,没有。除非您愿意自己修改lua解释器以使os.time使用您想要的分辨率,否则您将不得不安顿几秒钟。但是,这可能是不可接受的,如果您正在编写代码供其他人自己运行而不是像您可以完全控制环境的Web应用程序那样。

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

答案 3 :(得分:10)

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

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

首先是C代码,HighResTimer.c

////////////////////////////////////////////////////////////////
//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。

注意:我将HighResTimer.c编译为共享库Timer.so

#!/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");

注意:任何评论都是在将源代码粘贴到帖子编辑器之后编写的,所以从技术上来说这是未经测试的,但希望这些评论不会混淆。如果有的话,我一定会回来提供修复。

答案 4 :(得分:8)

lua得到毫秒

<德尔> os.time()

os.time()
return sec //only

posix.lock_gettime(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

socket.gettime()

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

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

waqas

比较&amp;测试

get_millisecond.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 :(得分:3)

凯夫拉尔是对的。

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

答案 6 :(得分:3)

如果你在lginx / openresty中使用lua,你可以使用ngx.now()返回一个精度为毫秒的浮点数

答案 7 :(得分:2)

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

来自文档:

  

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

答案 8 :(得分:0)

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

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

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

答案 9 :(得分:0)

如果您使用的是启用luajit的环境(例如OpenResty),则可以使用ffi访问基于C的时间函数,例如gettimeofday(),例如:(注意:{{1 }}仅当您反复运行pcall时才需要检查struct timeval的存在,例如通过OpenResty中的content_by_lua_file-没有它,您会遇到诸如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 gettimeofday()函数,以提供微秒级别精度的时钟时间。

答案 10 :(得分:0)

如果您的环境是 Windows 并且您可以访问系统命令,则可以使用 io.popen(command) 获得精确到厘米的时间:

hh:mm:ss.cc

结果将包含 "19:56:53.90\n" 格式的字符串:(带有尾随换行符)

.cc

请注意,它位于本地时区,因此您可能只想提取 os.time() 部分并将其与 var options = new chromeDriver.Options(); options.setUserPreferences({"profile.default_content_setting_values.automatic_downloads" : 1}); 的纪元秒数组合。