V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
EricJia
V2EX  ›  问与答

大红包 请教一个 rust 延迟的问题,

  •  
  •   EricJia · 2022-01-20 19:09:36 +08:00 · 1149 次点击
    这是一个创建于 1062 天前的主题,其中的信息可能已经有所发展或是发生改变。
    1. 在片段一中执行 解析 json 只需要 2us , 为何在 片段二中,加了行 sleep 代码后执行时间慢到 60us ?
    2. 为何 websocket 库中 read message loop 中解析 json 也是慢到 20-60us?

    rust 中 sleep 代码实现

    #[cfg(not(target_os = "espidf"))]
        pub fn sleep(dur: Duration) {
            let mut secs = dur.as_secs();
            let mut nsecs = dur.subsec_nanos() as _;
    
            // If we're awoken with a signal then the return value will be -1 and
            // nanosleep will fill in `ts` with the remaining time.
            unsafe {
                while secs > 0 || nsecs > 0 {
                    let mut ts = libc::timespec {
                        tv_sec: cmp::min(libc::time_t::MAX as u64, secs) as libc::time_t,
                        tv_nsec: nsecs,
                    };
                    secs -= ts.tv_sec as u64;
                    let ts_ptr = &mut ts as *mut _;
                    if libc::nanosleep(ts_ptr, ts_ptr) == -1 {
                        assert_eq!(os::errno(), libc::EINTR);
                        secs += ts.tv_sec as u64;
                        nsecs = ts.tv_nsec;
                    } else {
                        nsecs = 0;
                    }
                }
            }
        }
    
    use serde::{Serialize, Deserialize};
    use std::time::Instant;
    use std::time;
    
    use tungstenite::{connect,  Message};
    use url::Url;
    
    #[derive(Serialize, Deserialize)]
    pub struct OkexWsArg {
        pub channel: String,
        #[serde(rename(deserialize = "instId"))]
        pub inst_id: String,
    }
    #[derive(Serialize, Deserialize)]
    pub struct  OkexWsDepthItem {
        pub asks: [[String; 4]; 5],
        pub bids: [[String; 4]; 5],
        #[serde(rename(deserialize = "instId"))]
        pub inst_id: String,
        pub ts: String,
    }
    #[derive(Serialize, Deserialize)]
    pub struct OkexWsDepth {
        pub arg: OkexWsArg,
        pub data: [OkexWsDepthItem; 1],
    }
    
    fn main(){
        // 片段一
        for n in 0..10 {
            let start = Instant::now();
            let raw_msg = r#"{"arg":{"channel":"books5","instId":"BTC-USDT-SWAP"},"data":[{"asks":[["42185.1","959","0","32"],["42186.4","132","0","2"],["42186.7","6","0","6"],["42186.9","59","0","2"],["42187.2","19","0","2"]],"bids":[["42185","285","0","6"],["42183.3","15","0","1"],["42181.8","3","0","1"],["42181.7","6","0","3"],["42181.6","46","0","18"]],"instId":"BTC-USDT-SWAP","ts":"1642613619147"}]}"#;
            match  serde_json::from_str::<OkexWsDepth>(&raw_msg.to_string()) {
                Ok(msg) => {
                    println!("parse: {}", msg.data.first().unwrap().ts);
                },
                Err(err) => {
                    println!("parse error {:?} {:?}", raw_msg, err);
                }
            }
            println!("1-{} time cost: {:?} us",n, start.elapsed().as_micros());
        }
        // 片段二
        for n in 0..10 {
            std::thread::sleep(time::Duration::from_millis(100));
            let start = Instant::now();
            let raw_msg = r#"{"arg":{"channel":"books5","instId":"BTC-USDT-SWAP"},"data":[{"asks":[["42185.1","959","0","32"],["42186.4","132","0","2"],["42186.7","6","0","6"],["42186.9","59","0","2"],["42187.2","19","0","2"]],"bids":[["42185","285","0","6"],["42183.3","15","0","1"],["42181.8","3","0","1"],["42181.7","6","0","3"],["42181.6","46","0","18"]],"instId":"BTC-USDT-SWAP","ts":"1642613619147"}]}"#;
            match  serde_json::from_str::<OkexWsDepth>(&raw_msg.to_string()) {
                Ok(msg) => {
                    println!("parse: {}", msg.data.first().unwrap().ts);
                },
                Err(err) => {
                    println!("parse error {:?} {:?}", raw_msg, err);
                }
            }
            println!("2-{} time cost: {:?} us",n, start.elapsed().as_micros());
        }
    }
    
    
    2 条回复    2022-01-20 19:32:43 +08:00
    OSDI
        1
    OSDI  
       2022-01-20 19:20:10 +08:00 via Android
    sleep 进程挂起调度开销不小
    EricJia
        2
    EricJia  
    OP
       2022-01-20 19:32:43 +08:00
    @OSDI #1 感谢您的回答,请问在 websocket 库中 `tokio-tungstenite` `tungstenite` 等等 read message 循环中解析 json 延迟也很高, 也是因为类似原因吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4395 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 05:33 · PVG 13:33 · LAX 21:33 · JFK 00:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.