-- time.lua local ffi = require('ffi') local is_windows = (ffi.os == "Windows") -- Define C structures and functions based on platform if is_windows then ffi.cdef[[ typedef struct { int64_t QuadPart; } LARGE_INTEGER; int QueryPerformanceCounter(LARGE_INTEGER* lpPerformanceCount); int QueryPerformanceFrequency(LARGE_INTEGER* lpFrequency); ]] else ffi.cdef[[ typedef long time_t; typedef struct timeval { long tv_sec; long tv_usec; } timeval; int gettimeofday(struct timeval* tv, void* tz); time_t time(time_t* t); ]] end local time = {} local has_initialized = false local start_time, timer_freq -- Initialize timing system based on platform local function init() if has_initialized then return end if ffi.os == "Windows" then local frequency = ffi.new("LARGE_INTEGER") ffi.C.QueryPerformanceFrequency(frequency) timer_freq = tonumber(frequency.QuadPart) local counter = ffi.new("LARGE_INTEGER") ffi.C.QueryPerformanceCounter(counter) start_time = tonumber(counter.QuadPart) else -- Nothing special needed for Unix platform init start_time = ffi.C.time(nil) end has_initialized = true end -- PHP-compatible microtime implementation function time.microtime(get_as_float) init() if ffi.os == "Windows" then local counter = ffi.new("LARGE_INTEGER") ffi.C.QueryPerformanceCounter(counter) local now = tonumber(counter.QuadPart) local seconds = math.floor((now - start_time) / timer_freq) local microseconds = ((now - start_time) % timer_freq) * 1000000 / timer_freq if get_as_float then return seconds + microseconds / 1000000 else return string.format("0.%06d %d", microseconds, seconds) end else local tv = ffi.new("struct timeval") ffi.C.gettimeofday(tv, nil) if get_as_float then return tonumber(tv.tv_sec) + tonumber(tv.tv_usec) / 1000000 else return string.format("0.%06d %d", tv.tv_usec, tv.tv_sec) end end end -- High-precision monotonic timer (returns seconds with microsecond precision) function time.monotonic() init() if ffi.os == "Windows" then local counter = ffi.new("LARGE_INTEGER") ffi.C.QueryPerformanceCounter(counter) local now = tonumber(counter.QuadPart) return (now - start_time) / timer_freq else local tv = ffi.new("struct timeval") ffi.C.gettimeofday(tv, nil) return tonumber(tv.tv_sec) - start_time + tonumber(tv.tv_usec) / 1000000 end end -- Benchmark function that measures execution time function time.benchmark(func, iterations, warmup) iterations = iterations or 1000 warmup = warmup or 10 -- Warmup for i=1, warmup do func() end local start = time.microtime(true) for i=1, iterations do func() end local finish = time.microtime(true) local elapsed = (finish - start) * 1000000 -- Convert to microseconds return elapsed / iterations end -- Simple sleep function using coroutine yielding function time.sleep(seconds) if type(seconds) ~= "number" or seconds <= 0 then return end local start = time.monotonic() while time.monotonic() - start < seconds do -- Use coroutine.yield to avoid consuming CPU coroutine.yield() end end _G.microtime = time.microtime return time