mirror of
https://github.com/neovim/neovim.git
synced 2025-10-03 08:28:34 +00:00
viml/profile: switch to uv_gettimeofday() #10356
Performance of high-resolution time (clock_gettime via uv_hrtime) is
expensive on some systems. For profiling VimL, syntax, etc., we don't
care about nanosecond-precision and monotonicity edge-cases, so avoid
uv_hrtime().
closes #10328
From the uv__hrtime() source:
0cdb4a5b4b/src/unix/linux-core.c (L442-L462)
/* Prefer CLOCK_MONOTONIC_COARSE if available but only when it has
* millisecond granularity or better. CLOCK_MONOTONIC_COARSE is
* serviced entirely from the vDSO, whereas CLOCK_MONOTONIC may
* decide to make a costly system call.
*/
This micro-benchmark (Debug build) shows negligible differences on my
system:
#include <sys/time.h>
...
proftime_T tm = profile_start();
int trials = 999999;
int64_t t = 0;
struct timeval tv;
for (int i = 0; i < trials; i++) {
t += gettimeofday(&tv,NULL);
}
tm = profile_end(tm);
ILOG("%d trials of gettimeofday: %s", trials, profile_msg(tm));
tm = profile_start();
for (int i = 0; i < trials; i++) {
t += os_hrtime();
}
tm = profile_end(tm);
ILOG("%d trials of os_hrtime: %s", trials, profile_msg(tm));
tm = profile_start();
for (int i = 0; i < trials; i++) {
t += os_utime();
}
tm = profile_end(tm);
ILOG("%d trials of os_utime: %s", trials, profile_msg(tm));
ILOG("%zu", t);
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include "nvim/assert.h"
|
||||
#include "nvim/os/time.h"
|
||||
#include "nvim/os/input.h"
|
||||
#include "nvim/event/loop.h"
|
||||
@@ -22,6 +23,7 @@ static uv_cond_t delay_cond;
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "os/time.c.generated.h"
|
||||
#endif
|
||||
|
||||
/// Initializes the time module
|
||||
void time_init(void)
|
||||
{
|
||||
@@ -29,15 +31,53 @@ void time_init(void)
|
||||
uv_cond_init(&delay_cond);
|
||||
}
|
||||
|
||||
/// Obtain a high-resolution timer value
|
||||
/// Gets the current time with microsecond (μs) precision.
|
||||
///
|
||||
/// @return a timer value, not related to the time of day and not subject
|
||||
/// to clock drift. The value is expressed in nanoseconds.
|
||||
/// Subject to system-clock quirks (drift, going backwards, skipping).
|
||||
/// But it is much faster than os_hrtime() on some systems. #10328
|
||||
///
|
||||
/// @see gettimeofday(2)
|
||||
///
|
||||
/// @return Current time in microseconds.
|
||||
uint64_t os_utime(void)
|
||||
FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
uv_timeval64_t tm;
|
||||
int e = uv_gettimeofday(&tm);
|
||||
if (e != 0 || tm.tv_sec < 0 || tm.tv_usec < 0) {
|
||||
return 0;
|
||||
}
|
||||
uint64_t rv = (uint64_t)tm.tv_sec * 1000 * 1000; // s => μs
|
||||
STRICT_ADD(rv, tm.tv_usec, &rv, uint64_t);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/// Gets a high-resolution (nanosecond), monotonically-increasing time relative
|
||||
/// to an arbitrary time in the past.
|
||||
///
|
||||
/// Not related to the time of day and therefore not subject to clock drift.
|
||||
///
|
||||
/// @return Relative time value with nanosecond precision.
|
||||
uint64_t os_hrtime(void)
|
||||
FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
return uv_hrtime();
|
||||
}
|
||||
|
||||
/// Gets a millisecond-resolution, monotonically-increasing time relative to an
|
||||
/// arbitrary time in the past.
|
||||
///
|
||||
/// Not related to the time of day and therefore not subject to clock drift.
|
||||
/// The value is cached by the loop, it will not change until the next
|
||||
/// loop-tick (unless uv_update_time is called).
|
||||
///
|
||||
/// @return Relative time value with millisecond precision.
|
||||
uint64_t os_now(void)
|
||||
FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
return uv_now(&main_loop.uv);
|
||||
}
|
||||
|
||||
/// Sleeps for `ms` milliseconds.
|
||||
///
|
||||
/// @param ms Number of milliseconds to sleep
|
||||
|
Reference in New Issue
Block a user