Python 中 time模块 time.time() 是不是系统调用

原创 2017年07月09日 16:30:39

事情是这样的,最近公司自己定义了一个api规范,其中有一部分是请求时候用时间戳做 md5摘要。 然后我看到领导在文档中说 python 的 time.time() 是系统系统调用,调用的消耗太大,md5摘要中不用时间戳,而是用其他的字段。 于是我就不太相信这个说法。

线上的环境一般是 CentOS6.7 , CentOS 7, Python 的版本 2.6(惭愧),2.7。

下面的测试环境是 Centos6.7, Python2.6,我先来自己测测,然后在google吧。

两个问题
* 我们的环境中 time.time() 是否有系统调用?
* 这个函数的 cost 大到了无法承受的地步吗?

原文地址 http://blog.csdn.net/orangleliu/article/details/74892564

测试一

先写个简单的测试脚本吧, timetest.py

# coding:utf-8
import time

for i in xrange(10000000):
    time.time()

我们知道 linux 中time 命令可以显示出来 系统态和内核态使用的时间,先用 time 命令测下。

> time python timetest.py

real    0m1.793s
user    0m1.790s
sys    0m0.002s

结果叫人失望, 看起来 内核态没有多少时间,貌似不是个系统调用。

测试二

linux上有个使用的 工具叫做 perf,可以统计cpu使用时间。

> perf record -F 99 python timetest.py
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.017 MB perf.data (~730 samples) ]

> perf report

看看结果

28.84%  python  libpython2.6.so.1.0  [.] PyEval_EvalFrameEx
   9.43%  python  [kernel.kallsyms]    [.] vread_tsc
   8.32%  python  libpython2.6.so.1.0  [.] PyDict_GetItem
   5.72%  python  [kernel.kallsyms]    [k] __wake_up_bit
   4.44%  python  [vdso]               [.] __vdso_gettimeofday
   3.88%  python  libpython2.6.so.1.0  [.] _PyType_Lookup
   3.33%  python  libpython2.6.so.1.0  [.] PyObject_GenericGetAttr
   2.22%  python  libpython2.6.so.1.0  [.] 0x00000000000795a9
   1.66%  python  libpython2.6.so.1.0  [.] 0x00000000000795b0
   1.66%  python  [vdso]               [.] 0x000000000000082a
   1.66%  python  libpython2.6.so.1.0  [.] PyDict_SetItem
   1.66%  python  libpython2.6.so.1.0  [.] 0x00000000000796f0
   1.11%  python  timemodule.so        [.] 0x0000000000001e2a
   1.11%  python  libpython2.6.so.1.0  [.] 0x00000000000796f8
   1.11%  python  libpython2.6.so.1.0  [.] 0x00000000000795fd
   1.11%  python  [vdso]               [.] 0x0000000000000873
   1.11%  python  libpython2.6.so.1.0  [.] 0x0000000000079605
   1.11%  python  libpython2.6.so.1.0  [.] 0x000000000007823c
   1.11%  python  [vdso]               [.] 0x00000000000007e4
   1.11%  python  timemodule.so        [.] 0x0000000000001f13
   1.11%  python  libpython2.6.so.1.0  [.] PyObject_GetAttr@plt
   1.11%  python  libpython2.6.so.1.0  [.] _PyType_Lookup@plt
   1.11%  python  libpython2.6.so.1.0  [.] PyInt_FromLong
   0.55%  python  libpython2.6.so.1.0  [.] PyFloat_FromDouble
   0.55%  python  [vdso]               [.] 0x000000000000081f
....
   0.55%  python  timemodule.so        [.] 0x0000000000001e32
....
   0.55%  python  timemodule.so        [.] gettimeofday@plt

可以看到主要的开销,并不在 timemodule 啊。

思考

从上面的测试来看 ,这个函数的调用开销没想象中的那么大,看起来也不像是个系统调用。

开始找资料,首先是源码 python2.7 timemodule

static double
floattime(void)
{
    /* There are three ways to get the time:
      (1) gettimeofday() -- resolution in microseconds
      (2) ftime() -- resolution in milliseconds
      (3) time() -- resolution in seconds
      In all cases the return value is a float in seconds.
      Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
      fail, so we fall back on ftime() or time().
      Note: clock resolution does not imply clock accuracy! */
#ifdef HAVE_GETTIMEOFDAY
    {
        struct timeval t;
#ifdef GETTIMEOFDAY_NO_TZ
        if (gettimeofday(&t) == 0)
            return (double)t.tv_sec + t.tv_usec*0.000001;
#else /* !GETTIMEOFDAY_NO_TZ */
        if (gettimeofday(&t, (struct timezone *)NULL) == 0)
            return (double)t.tv_sec + t.tv_usec*0.000001;
#endif /* !GETTIMEOFDAY_NO_TZ */
    }

#endif /* !HAVE_GETTIMEOFDAY */
    {
#if defined(HAVE_FTIME)
        struct timeb t;
        ftime(&t);
        return (double)t.time + (double)t.millitm * (double)0.001;
#else /* !HAVE_FTIME */
        time_t secs;
        time(&secs);
        return (double)secs;
#endif /* !HAVE_FTIME */
    }
}

既然这里提到了 gettimeofday ,那么来看看这个调用吧。man 手册里面并未提到是系统调用

根据 Two frequently used system calls are ~77% slower on AWS EC2 ,这篇文章

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

int
main(int argc, char *argv[])
{
        struct timeval tv;
        int i = 0;
        for (; i<100; i++) {
                gettimeofday(&tv,NULL);
        }

        return 0;
}

编译完成用 strace 测试

> gcc -o test.exe  test.c
> strace -ce gettimeofday ./test.exe

并没发现系统调用。

最后来看看 陶辉老师的这篇文章吧 浅谈时间函数gettimeofday的成本

x86_64体系,gettimeofday是C库提供的函数(不是系统调用),它封装了内核里的sys_gettimeofday系统调用,就是说,归根到底是系统调用。

对于x86_64系统来说,这是个虚拟系统调用vsyscall!所以,这里它不用发送中断!速度很快,成本低,调用一次的成本大概不到一微秒!

好了,结果比较明显了,今天学到了点新知识,挺高兴!

版权声明:本文为orangleliu (http://blog.csdn.net/orangleliu/)原创文章,自由传播,文章转载请声明, 多谢。

python——time模块实现指定时间触发器

其实很简单,指定某个时间让脚本处理一个事件,比如说一个get请求~ 任何语言都会有关于时间的各种方法,python也不例外。 help(time)之后可以知道time有2种时间表示形式: 1、时间戳表...
  • sm9sun
  • sm9sun
  • 2016年12月05日 15:01
  • 2424

python 获取当天每个准点时间戳

import time,datetime def gettime(): for x in range(24): a = datetime.dat...
  • mzbqhbc12
  • mzbqhbc12
  • 2017年03月08日 23:25
  • 1447

python datetime time使用

欢迎使用Markdown编辑器写博客本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: Markdown和扩展Markdown简洁的语法 代码块高亮 图片链接和...
  • dabaiyang16
  • dabaiyang16
  • 2016年06月02日 16:28
  • 107

函数time()与gettimeofday()的区别

UNIX及Linux的时间系统是由「新纪元时间」Epoch开始计算起,单位为秒。Epoch是指定为1970年1月1日凌晨零点零分零秒,格林威治时间。目前大部份的UNIX系统都是用32位来记录时间,正值...
  • shanzhizi
  • shanzhizi
  • 2012年07月02日 15:39
  • 1680

C/C++获取时间方法:gettimeofday()

获取时间
  • u013652219
  • u013652219
  • 2015年04月18日 10:18
  • 9115

python 学习笔记 13 -- 常用的时间模块之time

完整的介绍Python 下的常用时间模块 time ~这在日常使用python 编程经常会用到,可能是用来显示时间,计时,乃至测试性能等。...
  • longerzone
  • longerzone
  • 2014年07月09日 10:11
  • 5792

python调用系统命令

大概有四种形式,的: 1.os.system('ls'):返回结果为该命令的返回值 2.tmp =os.popen('ls').readlines();将命令返回结果的返回给一个管道,然后读管道获取结...
  • wonderisland
  • wonderisland
  • 2013年12月04日 16:08
  • 6843

python模块:调用系统命令模块subprocess等

http://blog.csdn.net/pipisorry/article/details/46972171Python经常被称作“胶水语言”,因为它能够轻易地操作其他程序,轻易地包装使用其他语言编...
  • pipisorry
  • pipisorry
  • 2015年07月20日 18:38
  • 8844

Python系统调用——运行其他程序

在Python中可以方便地使用os模块运行其他的脚本或者程序,这样就可以在脚本中直接使用其他脚本,或者程序提供的功能,而不必再次编写实现该功能的代码。为了更好地控制运行的进程,可以使用win32pro...
  • ssihc0
  • ssihc0
  • 2012年07月12日 01:07
  • 22083

python执行系统命令四种方法比较

一、os模块1、os.system(cmd)在子终端运行系统命令,不能获取命令执行后的返回信息以及执行返回的状态import os os.system('date') # 2016年 06月 30日 ...
  • luckytanggu
  • luckytanggu
  • 2016年06月30日 20:35
  • 3456
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Python 中 time模块 time.time() 是不是系统调用
举报原因:
原因补充:

(最多只允许输入30个字)