< 返回版块

lizhichao 发表于 2023-11-20 11:42

Tags:时间

学习rust写了个计算时间的demo

use chrono::{DateTime, Utc, Datelike, Timelike,Duration};

struct Config {
    worker_day: [bool; 7], 
    worker_time: [bool; 24],
}

fn get_next_time(conf: &Config, start: &mut DateTime<Utc>, hour: u32) {
    let mut lh = hour;

    loop {
        let w = start.weekday() as usize;
        let h = start.hour() as usize;

        if conf.worker_day[w] && conf.worker_time[h] {
            if lh == 0 {
                break;
            }
            lh -= 1;
        }

        *start = *start + Duration::hours(1)
    }
}

fn main() {
   // test usage
   let  conf = Config{
       worker_day: [false, true, true, true, true, true, false],
       worker_time: [false, false, false, false, false, false, false, false,
       false, true, true, true, true, false, false, true,
       true, true, true, false, false, false, false, false],
   };

   use chrono::prelude::*;

   let mut nt = Utc.with_ymd_and_hms(2003,11, 20, 10, 0, 0).unwrap();

   get_next_time(&conf,
    &mut nt,
    1000000);

    println!("{:?}",nt)
}

比golang的性差好几倍,思路都是一样的 一个小时一个小时的判断

评论区

写评论
jerryshell 2023-12-28 09:03

我换成了 crates.io/crates/time 后,感觉差不多相当了

我这里 go 96ms,rust 106ms

下面是代码:

use time::ext::NumericalDuration;
use time::macros::datetime;

struct Config {
    worker_day: [bool; 7],
    worker_time: [bool; 24],
}

fn get_next_time(conf: &Config, start: &mut time::OffsetDateTime, hour: u32) {
    let mut remaining_hours = hour;

    while remaining_hours > 0 {
        let w = start.weekday() as usize;
        let h = start.hour() as usize;

        if conf.worker_day[w] && conf.worker_time[h] {
            remaining_hours -= 1;
        }

        *start += 1.hours();
    }
}

fn main() {
    // test usage
    let conf = Config {
        worker_day: [false, true, true, true, true, true, false],
        worker_time: [
            false, false, false, false, false, false, false, false, false, true, true, true, true,
            false, false, true, true, true, true, false, false, false, false, false,
        ],
    };

    let now = std::time::Instant::now();

    let mut nt = datetime!(2003-11-20 10:00 UTC);

    get_next_time(&conf, &mut nt, 1000000);

    println!("{:?} -- {:?}", nt, std::time::Instant::now() - now);
}
Cherrs 2023-11-22 15:27

确实chrono要慢,如果加上.naive_local()就不包含了时区了,如果程序跑在不同时区就会有问题。。

go上大分

--
👇
lizhichao: go (70-80)ms , 有大佬把入参改成
let mut nt = Utc.with_ymd_and_hms(2003,11, 20, 10, 0, 0).unwrap().naive_local() 性能会好的多 和 go相当

--
👇
我心飞翔: 应该是没有用 release, 我这里跑的结果是: cargo run --release Finished release [optimized] target(s) in 0.01s Running target/release/testchrono 2483-01-07T10:00:00Z, cost:188 ms

asuper 2023-11-21 19:08

https://rustcc.cn/article?id=4b701659-28e9-46e2-a4bf-5c58875e7dd7

你代码我没仔细看,追求速度的话,试试这个库,实测的确比chrono快很多

bestgopher 2023-11-20 15:51

记录下循环的次数是否一样呀

作者 lizhichao 2023-11-20 14:26

go (70-80)ms , 有大佬把入参改成
let mut nt = Utc.with_ymd_and_hms(2003,11, 20, 10, 0, 0).unwrap().naive_local() 性能会好的多 和 go相当

--
👇
我心飞翔: 应该是没有用 release, 我这里跑的结果是: cargo run --release Finished release [optimized] target(s) in 0.01s Running target/release/testchrono 2483-01-07T10:00:00Z, cost:188 ms

我心飞翔 2023-11-20 13:45

应该是没有用 release, 我这里跑的结果是: cargo run --release Finished release [optimized] target(s) in 0.01s Running target/release/testchrono 2483-01-07T10:00:00Z, cost:188 ms

作者 lizhichao 2023-11-20 11:44

golang代码

package main

import (
	"fmt"
	"time"
)

type Config struct {
	WorkerDay  []bool `json:"worker_day"`
	WorkerTime []bool `json:"worker_time"`
}

func GetNextTime(conf Config, start time.Time, hour int) time.Time {
	for {
		w := start.Weekday()
		h := start.Hour()

		if conf.WorkerDay[int(w)] && conf.WorkerTime[h] {
			if hour == 0 {
				break
			}
			hour--
		}

		start = start.Add(time.Hour)
	}

	return start
}

func main() {
	// test usage
	var conf Config
	conf.WorkerDay = []bool{
		false, true, true, true, true, true, false,
	}
	conf.WorkerTime = []bool{
		false, false, false, false, false, false, false, false,
		false, true, true, true, true, false, false, true,
		true, true, true, false, false, false, false, false,
	}

	// 2023-11-20 10:00:00
	nt := time.Now()
	st := "2003-11-20 10:00:00"
	t, _ := time.Parse(time.DateTime, st)
	next := GetNextTime(conf, t, 1000000)

	fmt.Println(next.Format(time.DateTime), " -- ", time.Now().Sub(nt).Milliseconds())

}

1 共 7 条评论, 1 页