Lua - Текущее время в миллисекундах - PullRequest
66 голосов
/ 21 января 2009

Есть ли распространенный способ получить текущее время в миллисекундах или с?

Существует os.time(), но он предоставляет только полные секунды.

Ответы [ 10 ]

57 голосов
/ 22 января 2009

Я использую LuaSocket для получения большей точности.

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

Конечно, это добавляет зависимость, но отлично подходит для личного использования (например, в сценариях бенчмаркинга).

52 голосов
/ 19 марта 2010

Если вы хотите провести сравнительный анализ, вы можете использовать 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))
33 голосов
/ 21 января 2009

В стандарте C lua, нет. Вам придется согласиться на несколько секунд, если только вы сами не захотите изменить интерпретатор lua, чтобы в другое время использовать желаемое разрешение. Однако это может быть неприемлемо, если вы пишете код для других людей, который запускается самостоятельно, а не как веб-приложение, в котором вы полностью контролируете среду.

Редактировать: другой вариант - написать свою маленькую DLL на C, которая расширяет lua новой функцией, которая даст вам нужные значения и требует, чтобы dll распространялась вместе с вашим кодом, кому бы он ни собирался его использовать.

10 голосов
/ 16 апреля 2012

Я сделал подходящее решение для lua на Windows. Я в основном сделал то, что предложил Кевлар, но с общей библиотекой, а не с DLL. Это было проверено с использованием Cygwin.

Я написал некоторый совместимый с lua код C, скомпилировал его в общую библиотеку (.so файл через gcc в cygwin), а затем загрузил его в lua с помощью package.cpath и потребовал "". Написал скрипт адаптера для удобства. Вот весь источник:

первый код 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");

Примечание: любые комментарии были написаны после вставки исходного кода в редактор сообщений, так что технически это не проверено, но, надеюсь, комментарии ничего не запутали. Я обязательно вернусь и предоставлю исправления, если это произойдет.

8 голосов
/ 22 марта 2017

Получить текущее время в миллисекундах.

os.time ()

os.time()
return sec // only

posix.clock_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 говорит


сравнить и проверить

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
3 голосов
/ 18 июня 2015

Если вы используете lua с nginx / openresty, вы можете использовать ngx.now () , который возвращает число с плавающей точкой с точностью до миллисекунды

3 голосов
/ 21 января 2009

Кевлар правильный.

Альтернативой пользовательской DLL является Lua Alien

2 голосов
/ 16 марта 2016

в опенресте есть функция ngx.req.start_time .

Из документов:

Возвращает число с плавающей точкой, представляющее метку времени (включая миллисекунды в качестве десятичной части), когда был создан текущий запрос.

0 голосов
/ 09 мая 2019

Если вы используете среду с поддержкой luajit , такую ​​как OpenResty, то вы можете использовать ffi для доступа к функциям времени на основе C, таким как gettimeofday(), например: (Примечание: 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 gettimeofday(), чтобы обеспечить время на часах с точностью до микросекунды .

0 голосов
/ 15 марта 2009

Вы можете использовать функцию C gettimeofday: http://www.opengroup.org/onlinepubs/000095399/functions/gettimeofday.html

Здесь C библиотека 'ul_time', функция sec_usec находится в глобальной таблице 'time' и возвращает секунды, useconds. Скопируйте DLL в папку Lua, откройте ее с помощью require 'ul_time'.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...