Skip to content

time.clock_gettime_ns() is too slow #111482

Closed

Description

@socketpair

Feature or enhancement

Proposal:

Actually, this is a performance bug. Not a feature/enhancement.
clock_gettime_ns() does not use floating point operations and should be faster than old gettimeofday(). Unfotunately in Python it's not so. Checked in Linux X86_64 kernel 6.5.7, CPython 3.11.6

In [11]: timeit time.clock_gettime_ns(0)  # CLOCK_REALTIME
55.4 ns ± 1.22 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

In [12]: timeit time.clock_gettime_ns(5) # CLOCK_REALTIME_COARSE
45 ns ± 0.324 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

In [13]: timeit time.time()
36.7 ns ± 0.953 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

Linked PRs

Activity

  1. changed the title [-]time.clock_gettime_ns is too slow[/-] [+]time.clock_gettime_ns() is too slow[/+] on Oct 30, 2023
  2. added
    performancePerformance or resource usage
    and removed
    type-featureA feature request or enhancement
    on Oct 30, 2023
  3. pochmann commented on Oct 30, 2023

    @pochmann
    Contributor

    "too slow" for what?

  4. socketpair commented on Oct 30, 2023

    @socketpair
    ContributorAuthor

    @pochmann too slow comparing to time.time() = gettimeofday(). For example, CLOCK_REALTIME_COARSE by definition should be faster (but coarse). In fact, it's not faster in Python. I did a glimpse on the implementation. For reasons that I don't understand, there are many useless wrappers around simple things.

    Why not to do this:

    static PyObject *
    time_clock_gettime_ns(PyObject *self, PyObject *args)
    {
        int clk_id;
        if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) {
            return NULL;
        }
    
        struct timespec ts;
        if (clock_gettime((clockid_t)clk_id, &ts)) {
            PyErr_SetFromErrno(PyExc_OSError);
            return NULL;
        }
    
        return PyLong_FromLongLong(ts.tv_sec * 1000000000ll + ts.tv_nsec);
    }

    I beat, it will be faster than current implementation, although I did not check yet.

  5. vstinner commented on Nov 1, 2023

    @vstinner
    Member

    I'm not sure what this issue is about. If you want to propose a change, go ahead.

  6. socketpair commented on Nov 2, 2023

    @socketpair
    ContributorAuthor

    I have checked, my optimizations give nothing, so closing the issue :(

  7. added 3 commits that reference this issue on Nov 2, 2023
  8. vstinner commented on Nov 2, 2023

    @vstinner
    Member

    I reopen the issue: I wrote PR #111641 which makes clock_gettime() and clock_gettime_ns() up to 2x faster by using a faster calling convention (METH_VARARGS => METH_O).

  9. added a commit that references this issue on Nov 2, 2023
  10. added a commit that references this issue on Nov 3, 2023
  11. hugovk commented on Nov 9, 2023

    @hugovk
    Member

    #111641 was merged. Does it need backporting? If not, let's close this issue.

  12. vstinner commented on Nov 9, 2023

    @vstinner
    Member

    I dislike backporting optimizations. Better performance is not worth it compared to the risk of regression. I close the issue. Thanks @socketpair for the bug report.

  13. added 2 commits that reference this issue on Nov 16, 2023
  14. added 2 commits that reference this issue on Feb 11, 2024
  15. added 2 commits that reference this issue on Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    performancePerformance or resource usage

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions