How To Find Time Difference using Chrono library in Rust - time

I have a Rust program where I want to do some simple benchmarking with start time and end time!
use chrono::{NaiveTime, Utc};
fn main() {
let start_time: NaiveTime = Utc::now().time();
let end_time: NaiveTime = Utc::now().time();
println!("Total time taken to run is {}", end_time - start_time);
}
The code above prints as:
Total time taken to run is PT520.532696S
I guess it is 520 seconds if I'm not wrong, but how can I convert that into minutes? Is there a better way?

A simple look to the doc give the answer:
use chrono::Utc;
fn main() {
let start_time = Utc::now().time();
let end_time = Utc::now().time();
let diff = end_time - start_time;
println!("Total time taken to run is {}", diff.num_minutes());
}
but be aware that it's not a good way to mesure time in a monotonic way, this code could show -5 minutes if user change the system date somehow. Also call time() remove the information of the date, and this is strange when you use chrono because generally you don't want to ignore the date so just remove time() call.

It seems the accepted answer has some potential flaws.
A potentially better way as recommended in the rust nursery
is the following:
use std::time::{Duration, Instant};
use std::thread;
fn expensive_function() {
thread::sleep(Duration::from_secs(1));
}
fn main() {
let start = Instant::now();
expensive_function();
let duration = start.elapsed();
println!("Time elapsed in expensive_function() is: {:?}", duration);
}

Related

Having trouble with comparing datetimes, when there are DB, Golang and Unix versions

So, basically a person has a shift, with a start time and duration, and I need to know how many minutes to go.
I retrieve from the database (mySQL) a standard string of datetime for the start of the shift (eg. 2022-01-01 09:00:00)
I also retrieve the number of hours of the shift (eg. 8)
I can then determine current time, using Golang's Time.time, but this format is different.
Please see code below, which explains the problem better, and gives the pieces missing.
Thanks!
var shiftStartDB string // For example 2022-01-01 09:00:00
var shiftStartUnix int // For example, start time converted to minutes since epoch
var offTimer int // Number of hours for the shift
var shiftEndDB string // For example 2022-01-01 17:00:00
var shiftEndUnix int // For example, end time converted to minutes since epoch
var nowTime Time.time // Golangs version of time for now
var nowUnix int // Golang now converted to Unix time
var templateID string
var minsToGo int
_ = db.QueryRow("SELECT LastSignedOn, OffTimer, TemplateID FROM assets WHERE ID = ?", assetid).Scan(&shiftStartDB, &offTimer, &templateID)
shiftStartUnix = <convert database time into unix time>
if offTimerTemp == 0 {
_ = db.QueryRow("OffTimer FROM templates WHERE ID = ?", templateID).Scan(&offTimer)
}
shiftEndUnix = shiftStartUnix + (offTimer * 60)
nowTime = time.Now()
nowUnix = <convert golang time into unix time>
minsToGo = shiftEndInt - nowInt
You can use nowUnix = nowTime.UNIX()/60, as Time.UNIX returns the number of seconds elapsed since epoch. that said, this might be easier to deal with if you parsed the times and used go library time functions directly:
shiftStartTime,err := time.Parse("2006-02-01 15:04:05",dbTime)
shiftEnd=shiftStartTime.Add(time.Hour*offTimer)
minsToGo:=shiftEnd.Sub(time.Now()).Minutes()

Why enum value binding in Rust is so slow?

I am currently learning Rust because I wanted to use it in project that requires a very high performance. I initially fallen in love with enums but then I started to evaluate their performance and I have found something that is really boggling me. Here is an example:
use std::time::{Instant};
pub enum MyEnum<'a> {
V1,
V2(&'a MyEnum<'a>),
V3,
}
impl MyEnum<'_> {
pub fn eval(&self) -> i64 {
match self {
MyEnum::V1 => 1,
MyEnum::V2(_) => 2,
MyEnum::V3 => 3,
}
}
pub fn eval2(&self) -> i64 {
match self {
MyEnum::V1 => 1,
MyEnum::V2(a) => a.eval2(),
MyEnum::V3 => 3,
}
}
}
fn main() {
const EXAMPLES: usize = 10000000;
let en = MyEnum::V1{};
let start = Instant::now();
let mut sum = 0;
for _ in 0..EXAMPLES {
sum += en.eval()
}
println!("enum without fields func call sum: {} at {:?}", sum, start.elapsed());
let start = Instant::now();
let mut sum = 0;
for _ in 0..EXAMPLES {
sum += en.eval2()
}
println!("enum with field func call sum: {} at {:?}", sum, start.elapsed());
}
Results I get:
enum without fields func call sum: 10000000 at 100ns
enum with field func call sum: 10000000 at 6.3425ms
eval function should execute exactly the same instructions as eval2 for V1 enum but it's working about 60x slower. Why is this happening?
Viewing the assembly, your first loop is optimized entirely into a single mov 10000000 instruction (that is, the compiler does something equivalent to sum += EXAMPLES) while the second is not. I do not know why the second loop is not constant-optimized as heavily.
I see no difference in performance, as one would expect.
$ ./test
enum without fields func call sum: 10000000 at 307.543596ms
enum with field func call sum: 10000000 at 312.196195ms
$ rustc --version
rustc 1.43.1 (8d69840ab 2020-05-04)
$ uname -a
Darwin Windhund.local 18.7.0 Darwin Kernel Version 18.7.0: Mon Feb 10 21:08:45 PST 2020; root:xnu-4903.278.28~1/RELEASE_X86_64 x86_64 i386 MacBookPro15,2 Darwin
One problem might be the use of simple "wall clock" time for benchmarking. This simple count of how much time passed is vulnerable to anything else running which might consume resources. Anti-virus, a web browser, any program. Instead, use benchmark tests.

Windows SYSTEMTIME structure different then System clock?

The goal of the following code is to call the Win32 function FileTimeToSystemTime:
pub fn convert_times(s: SystemTime) -> Option<SYSTEMTIME> {
let mut st = SYSTEMTIME::default();
let x: u64 = unsafe { transmute(s) };
let low = (x & 0x00000000FFFFFFFF) as u32;
let high = ((x & 0xFFFFFFFF00000000) >> 32) as u32;
let fs = FILETIME {
dwLowDateTime: low,
dwHighDateTime: high,
};
if unsafe { FileTimeToSystemTime(transmute(&fs), transmute(&mut st)) } > 0 {
Some(st)
} else {
None
}
}
When I take a known file time 131147233180069965 which was generated at 2016-08-03T14:41 US-EST(GMT+5) according to my computer's clock. The return structure I get from this returns 2016-0803T18:41:58.006
This is +4 hours.
While US-EST is GMT+5?
Is it because Daylight Saving Time is -1hr?
FileTimeToLocalFileTime() returns time at UTC. In the United States, locations normally in EST transition to EDT during Daylight Saving Time, so it will be GMT+5 DST-1 or UTC-4.
To get time in the local timezone and take DST into account, one would instead need to call SystemTimeToTzSpecificLocalTime().
Generally this inadvisable as working in UTC is preferable for computers as 2 intercommunicating computers are not necessarily in the same timezone.

dispatch_get_main_queue() doesn't run new async jobs smoothly

let dispatchGroup = dispatch_group_create()
let now = DISPATCH_TIME_NOW
for i in 0..<1000 {
dispatch_group_enter(dispatchGroup)
// Do some async tasks
let delay = dispatch_time(now, Int64(Double(i) * 0.1 * Double(NSEC_PER_SEC)))
dispatch_after(delay, dispatch_get_main_queue(), {
print(i)
dispatch_group_leave(dispatchGroup)
})
}
The print statement can print first 15-20 numbers smoothly, however, when i goes larger, the print statement prints stuff in a sluggish way. I had more complicated logic inside dispatch_after and I noticed the processing was very sluggish, that's why I wrote this test.
Is there a buffer size or other properties that I can configure? It seems dispatch_get_main_queue() doesn't work well with bigger number of async tasks.
Thanks in advance!
The problem isn't dispatch_get_main_queue(). (You'll notice the same behavior if you use a different queue.) The problem rests in dispatch_after().
When you use dispatch_after, it creates a dispatch timer with a leeway of 10% of the start/when. See the Apple github libdispatch source. The net effect is that when these timers (start ± 10% leeway) overlap, it may start coalescing them. When they're coalesced, they'll appear to fire in a "clumped" manner, a bunch of them firing immediately right after another and then a little delay before it gets to the next bunch.
There are a couple of solutions, all entailing the retirement of the series of dispatch_after calls:
You can build timers manually, forcing DispatchSource.TimerFlag.strict to disable coalescing:
let group = DispatchGroup()
let queue = DispatchQueue.main
let start = CACurrentMediaTime()
os_log("start")
for i in 0 ..< 1000 {
group.enter()
let timer = DispatchSource.makeTimerSource(flags: .strict, queue: queue) // use `.strict` to avoid coalescing
timer.setEventHandler {
timer.cancel() // reference timer so it has strong reference until the handler is called
os_log("%d", i)
group.leave()
}
timer.schedule(deadline: .now() + Double(i) * 0.1)
timer.resume()
}
group.notify(queue: .main) {
let elapsed = CACurrentMediaTime() - start
os_log("all done %.1f", elapsed)
}
Personally, I dislike that reference to timer inside the closure, but you need to keep some strong reference to it until the timer fires, and GCD timers release the block (avoiding strong reference cycle) when the timer is canceled/finishes. This is inelegant solution, IMHO.
It is more efficient to just schedule single repeating timer that fires every 0.1 seconds:
var timer: DispatchSourceTimer? // note this is property to make sure we keep strong reference
func startTimer() {
let queue = DispatchQueue.main
let start = CACurrentMediaTime()
var counter = 0
// Do some async tasks
timer = DispatchSource.makeTimerSource(flags: .strict, queue: queue)
timer!.setEventHandler { [weak self] in
guard counter < 1000 else {
self?.timer?.cancel()
self?.timer = nil
let elapsed = CACurrentMediaTime() - start
os_log("all done %.1f", elapsed)
return
}
os_log("%d", counter)
counter += 1
}
timer!.schedule(deadline: .now(), repeating: 0.05)
timer!.resume()
}
This not only solves the coalescing problem, but it also is more efficient.
For Swift 2.3 rendition, see previous version of this answer.

Lua - Current time in milliseconds

Is there a common way to get the current time in or with milliseconds?
There is os.time(), but it only provides full seconds.
I use LuaSocket to get more precision.
require "socket"
print("Milliseconds: " .. socket.gettime()*1000)
This adds a dependency of course, but works fine for personal use (in benchmarking scripts for example).
If you want to benchmark, you can use os.clock as shown by the doc:
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))
In standard C lua, no. You will have to settle for seconds, unless you are willing to modify the lua interpreter yourself to have os.time use the resolution you want. That may be unacceptable, however, if you are writing code for other people to run on their own and not something like a web application where you have full control of the environment.
Edit: another option is to write your own small DLL in C that extends lua with a new function that would give you the values you want, and require that dll be distributed with your code to whomever is going to be using it.
Get current time in milliseconds.
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
as waqas says
compare & test
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
output
lua get_millisecond.lua
1490186718
1490186718 268570540
1490186718.2686
1490186718
1490186718 268662191
1490186718.2687
1490186718
1490186718 268782765
1490186718.2688
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 <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;
}
--
--
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.
If you're using lua with nginx/openresty you could use ngx.now() which returns a float with millisecond precision
If you're using OpenResty then it provides for in-built millisecond time accuracy through the use of its ngx.now() function. Although if you want fine grained millisecond accuracy then you may need to call ngx.update_time() first. Or if you want to go one step further...
If you are using luajit enabled environment, such as OpenResty, then you can also use ffi to access C based time functions such as gettimeofday() e.g: (Note: The pcall check for the existence of struct timeval is only necessary if you're running it repeatedly e.g. via content_by_lua_file in OpenResty - without it you run into errors such as 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
Then the new lua gettimeofday() function can be called from lua to provide the clock time to microsecond level accuracy.
Indeed, one could take a similar approaching using clock_gettime() to obtain nanosecond accuracy.
Kevlar is correct.
An alternative to a custom DLL is Lua Alien
in openresty there is a function ngx.req.start_time.
From the docs:
Returns a floating-point number representing the timestamp (including milliseconds as the decimal part) when the current request was created.
You can use C function gettimeofday :
http://www.opengroup.org/onlinepubs/000095399/functions/gettimeofday.html
Here C library 'ul_time', function sec_usec resides in 'time' global table and returns seconds, useconds. Copy DLL to Lua folder, open it with require 'ul_time'.
http://depositfiles.com/files/3g2fx7dij
If you're on a system with a GNU-compatible implementation of date that you can execute, here's a one-liner to get the Epoch time in milliseconds:
local function gethammertime()
return tonumber(assert(assert(io.popen'date +%s%3N'):read'a'))
end
Note that the assert calls are necessary to ensure that any failures to read or open date will propagate the errors, respectively. Also note that this relies on garbage collection (or finalizers, in Lua 5.4) to close the process handle: if using a pre-5.4 version of Lua and resource exhaustion is a concern, you may wish to extend this to three lines like Klesun's Windows-based answer and close the handle explicitly.
If your environment is Windows and you have access to system commands, you can get time of centiseconds precision with io.popen(command):
local handle = io.popen("echo %time%")
local result = handle:read("*a")
handle:close()
The result will hold string of hh:mm:ss.cc format: (with trailing line break)
"19:56:53.90\n"
Note, it's in local timezone, so you probably want to extract only the .cc part and combine it with epoch seconds from os.time().

Resources