I’m trying to determine the fastest way to add UTC time stamps with a resolution of 1 s to automated logs of data reading and processing. This is used frequently as data are read into memory and processed. Suggestions would be welcome; my questions are at the bottom.
Trial solutions below are adapted from Higher resolution DateTime/TimeStamp - #45 by yakir12 . The first two give higher-resolution time stamps than I need, but that’s fine for comparison purposes.
using AstroTime, BenchmarkTools, Dates, Base.Libc
timestamp0() = string(Dates.now(Dates.UTC))
timestamp1() = string(AstroTime.now()) # not UTC??
function timestamp2()
t = Dates.unix2datetime(Dates.time())
Y, M, D, h, m, s = year(t), month(t), day(t),
hour(t), minute(t), second(t)
Ys = lpad(Y, 4, "0")
Ms = lpad(M, 2, "0")
Ds = lpad(D, 2, "0")
hs = lpad(h, 2, "0")
ms = lpad(m, 2, "0")
ss = lpad(s, 2, "0")
return string(Ys, "-", Ms, "-", Ds, "T", hs, ":", ms, ":", ss)
end
I swear I’m 20 years rusty at C and not even fond of external calls, but then there’s this, adapted from Getting the value of a pointer in Julia | juliabloggers.com …
mutable struct TBuf
t::Base.RefValue{Int64}
m::TmStruct
b::Array{UInt8,1}
f::String
p::Ptr{UInt8}
function TBuf()
T = new(Ref{Int64}(0), TmStruct(), zeros(UInt8,20),
"%FT%T", Ptr{UInt8}())
T.p = pointer(T.b)
return T
end
end
const T = TBuf()
function timestamp3()
ccall(:time, Nothing, (Ptr{Int64},), T.t)
ccall(Sys.iswindows() ? :gmtime_s : :gmtime_r, Nothing,
(Ptr{Int64}, Ref{TmStruct}), T.t, T.m)
ccall(:strftime, Nothing,
(Cstring, Cint, Cstring, Ref{TmStruct}),
T.p, Int32(20), T.f, T.m)
return unsafe_string(T.p)
end
Results
Intel(R) Core™ i7-6820HQ CPU @ 2.70GHz
15862 MiB RAM
Ubuntu 18.04 (bionic)
Julia 1.3.1
Method | Mem | t |
---|---|---|
timestamp0 | 912 B | 701.199 ns |
timestamp1 | 1.63 KB | 3.610 μs |
timestamp2 | 688 B | 584.849 ns |
timestamp3 | 48 B | 313.776 ns |
My questions
- Are the C calls in
timestamp3()
safe as written? Do I need to set appropriate return Types, even though they modify variables in-place, or can I leave as Nothing? - Is a memory-resident structure with Ref and Ptr as fields OK, or is this a spectacularly bad idea? For example, are there gc issues?
- Any suggestions that I might have missed?
Thanks, and my apologies for the length of the post.