Lua - Current time in milliseconds

后端 未结 10 974
自闭症患者
自闭症患者 2020-12-01 01:56

Is there a common way to get the current time in or with milliseconds?

There is os.time(), but it only provides full seconds.

10条回答
  •  猫巷女王i
    2020-12-01 02:18

    I made a suitable solution for lua on Windows. I basically did what Kevlar suggested, but with a shared library rather than a DLL. This has been tested using cygwin.

    I wrote some lua compatible C code, compiled it to a shared library (.so file via gcc in cygwin), and then loaded it up in lua using package.cpath and require" ". Wrote an adapter script for convenience. Here is all of the source:

    first the C code, 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 
    
    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;
    }
    

    --

    --

    Now lets get it loaded up in a lua script, HighResTimer.lua .

    Note: I compiled the HighResTimer.c to a shared library, 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
    

    --

    --

    and Finally, utilize the timer, 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");
    

    Note: Any comments were written after pasting the source code into the post editor, so technically this is untested, but hopefully the comments didn't befuddle anything. I will be sure to come back and provide a fix if it does.

提交回复
热议问题