Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Local is horribly slow when used in multi-threads #277

Closed
breezewish opened this issue Sep 4, 2018 · 4 comments
Closed

Local is horribly slow when used in multi-threads #277

breezewish opened this issue Sep 4, 2018 · 4 comments

Comments

@breezewish
Copy link

#![feature(test)]

extern crate test;
extern crate chrono;
extern crate chrono_tz;
extern crate tzdata;

use chrono::prelude::*;
use chrono_tz::Tz;
use std::thread;
use std::sync::Arc;

fn multithread_iter<F>(f: F)
where
    F: Fn() + Send + Sync + 'static,
{
    let f = Arc::new(f);
    let mut handles = vec![];
    for _ in 0..4 {
        let f = f.clone();
        handles.push(thread::spawn(move || {
            for _ in 0..test::black_box(500) {
                f();
            }
        }));
    }
    for handle in handles {
        handle.join().unwrap();
    }
}

#[bench]
fn bench_local(b: &mut test::Bencher) {
    b.iter(|| {
        multithread_iter(|| {
            let time = chrono::Utc.timestamp(test::black_box(1500000000), 0);
            let local_time = time.with_timezone(&chrono::Local);
            let output = local_time.format("%Y-%m-%d %H:%M:%S").to_string();
            test::black_box(output);
        });
    });
}

#[bench]
fn bench_fixed_offset(b: &mut test::Bencher) {
    let utc7 = FixedOffset::east(7 * 3600);
    b.iter(|| {
        multithread_iter(move || {
            let time = chrono::Utc.timestamp(test::black_box(1500000000), 0);
            let local_time = time.with_timezone(test::black_box(&utc7));
            let output = local_time.format("%Y-%m-%d %H:%M:%S").to_string();
            test::black_box(output);
        });
    });
}

#[bench]
fn bench_utc(b: &mut test::Bencher) {
    b.iter(|| {
        multithread_iter(|| {
            let time = chrono::Utc.timestamp(test::black_box(1500000000), 0);
            let local_time = time.with_timezone(&chrono::Utc);
            let output = local_time.format("%Y-%m-%d %H:%M:%S").to_string();
            test::black_box(output);
        });
    });
}

#[bench]
fn bench_tz_name(b: &mut test::Bencher) {
    let tz: Tz = "Asia/Shanghai".parse().unwrap();
    b.iter(|| {
        multithread_iter(move || {
            let time = chrono::Utc.timestamp(test::black_box(1500000000), 0);
            let local_time = time.with_timezone(&tz);
            let output = local_time.format("%Y-%m-%d %H:%M:%S").to_string();
            test::black_box(output);
        });
    });
}

On my Macbook MacOS:

test bench_fixed_offset ... bench:     797,370 ns/iter (+/- 395,501)
test bench_local        ... bench: 440,913,480 ns/iter (+/- 33,827,703)
test bench_tz_name      ... bench:     733,082 ns/iter (+/- 213,310)
test bench_utc          ... bench:     724,654 ns/iter (+/- 135,656)

On one Linux machine:

test bench_fixed_offset ... bench:   1,181,716 ns/iter (+/- 495,258)
test bench_local        ... bench:   3,191,669 ns/iter (+/- 528,632)
test bench_tz_name      ... bench:   1,035,763 ns/iter (+/- 390,355)
test bench_utc          ... bench:     957,221 ns/iter (+/- 311,527)

On another Linux machine:

test bench_fixed_offset ... bench:   1,602,190 ns/iter (+/- 521,638)
test bench_local        ... bench:   9,077,729 ns/iter (+/- 994,012)
test bench_tz_name      ... bench:   1,471,818 ns/iter (+/- 222,253)
test bench_utc          ... bench:   1,410,985 ns/iter (+/- 235,519)
@breezewish
Copy link
Author

breezewish commented Sep 4, 2018

Wrote another benchmark directly use time crate. Although it is still somehow slow, it is better than current one:

#[bench]
fn bench_time(b: &mut test::Bencher) {
    b.iter(|| {
        multithread_iter(move || {
            let tm = time::at(time::Timespec::new(test::black_box(1500000000), 0));
            test::black_box(tm);
        });
    });
}

On my Macbook MacOS:

test bench_time         ... bench:  16,177,259 ns/iter (+/- 1,343,755)

On one Linux machine:

test bench_time         ... bench:   1,878,481 ns/iter (+/- 438,255)

On another Linux machine:

test bench_time         ... bench:   2,712,806 ns/iter (+/- 6,413,237)

@pitdicker
Copy link
Collaborator

This part of chrono has been significantly reworked. Results on my Linux pc:

test bench_fixed_offset ... bench:     808,263 ns/iter (+/- 57,325)
test bench_local        ... bench:     908,429 ns/iter (+/- 45,946)
test bench_utc          ... bench:     741,940 ns/iter (+/- 27,885)

The same implementation is used on MacOS.

@breezewish It has been many years. Do you want to re-run your benchmark?

@breezewish
Copy link
Author

@pitdicker Cool, thanks for the benchmark!

@djc
Copy link
Member

djc commented Jun 7, 2023

@breezewish thanks for following up so quickly after all those years!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants