python;从epoch到weekday/weekend的超快速转换,分钟

2024-04-20 01:30:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图把数百万个时代转换成一个元组(X,Y),其中X(布尔值)是不是周末,Y是一天中的分钟,它在(01440)范围内

转换为datetime的简单、正确的方法是:

def _epoch_to_dinfo(epoch):
    d = datetime.utcfromtimestamp(epoch) #SLOW AS F
    is_weekday = d.isoweekday() in range(1, 6)
    minute_of_day = d.hour*60 + d.minute
    return is_weekday, minute_of_day

太慢了。我正在寻找一个近似值;下面是我最好的尝试:

^{pr2}$

有没有更快的方法?在


Tags: ofto方法datetimeisdef元组slow
2条回答

假设您真的需要这样的速度,唯一可以节省的(在CPython中)是减少正在执行的字节码的数量,甚至存储到本地也需要额外的字节码工作(即使它对每个字节码指令没有太多工作,仅仅处理它们也会有开销)。因此,基本上,最小化中间存储(因此也减少字节码),方法是像注释掉的代码一样对其进行一次线性化(尽管在非常旧的Python上,not in检查需要一个tuple常量,以避免Python每次愚蠢地重建一个list):

def _epoch_to_dinfo(epoch):  
    return (epoch // 86400) % 7 not in (2, 3), (epoch % 86400) // 60

仅凭一行代码,我在python2.7x86安装中的每次运行成本就下降了约23%。在

您可能认为可以使用divmod一次计算除以86400的epoch的商和余数,但是从内置命名空间查找divmod(由于LEGB search而昂贵),调用它(比基于语法的调用,如//%)的开销要大得多,打开结果并加载从堆栈返回的未打包结果意味着它最终的成本甚至比非一行解决方案还要高;除非输入足够大,以至于实际完成的数学工作大大超过查找开销和函数调用开销(这通常意味着数字必须足够大,才能调用基于数组的数学,然后再调用一些;在Py2中使用long,或者在32位和64位系统中使用超过digit大小的int,对于32位和64位系统,则为15或30位,在Py3中,divmod几乎永远不会节省时间。在

类似地,对not in (2, 3)的测试胜过所有其他方法,这不是因为它在逻辑上更快,而是因为它简化为常量tupleLOAD_CONST,并为not in调用{}(之后在C层进行比较);针对2和3的单独测试将加载更多的常量,调用更多的{}s并执行在Python字节码中使用条件跳转之类的,这样的代价更高。在

这条建议中没有一条适用于CPython之外的任何解释器(而且大部分可能只适用于cpython2.7),因为它都是实现细节。在

你可以预先计算出所有的星期六和星期日,然后把它们放进字典里,以纪元后的天数为键。然后你可以这样做:

saturdays = {d: True for d in range(2,5000,7)}  # pre-calculate
sundays = {d: True for d in range(3,5000,7)}
saturdays_and_sundays = {**saturdays, **sundays} # join dicts (Python 3.5+)

# in your function
days_since_epoch = epoch / 86400
minute_of_day = (epoch % 86400) / 60
if days_since_epoch in saturdays_and_sundays :
    return True, minute_of_day
return False, minute_of_day

相关问题 更多 >