-
Notifications
You must be signed in to change notification settings - Fork 533
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
Getting time and formatting it seems slow. #94
Comments
I'm right on the trip and the reply may be not quick. That said...
Time zone is a local concept to the current process, normally implemented as a part of libc (glibc has tons of the code dedicated for this, and includes a complete reader for tzfile). Right now Chrono depends on libtime for this task, that is AFAIK just a call to I'm actually thinking of replacing them with an independent implementation (I've met some crazy bugs from libtime), and I guess
The following code would be equivalent (untested): use chrono::format::{Item, Fixed};
datetime.format_with_items([Item::Fixed(Fixed::RFC3339)].iter().cloned()) I think this should be reasonably fast, but it still depends on the entire formatting architecture of Rust that is not very fast. (It does not allocate, but has tons of indirections.) I believe Chrono excels at breaking the time components apart, though.
|
Thank you very much for the answer. Very informative. I'm not really blocked by this in any way. The timestamp is lazily evaluated - only when required so it's not a big deal, but obviously it would be better if it was as fast as possible, so I brought it to your attention. |
Okay, I've actually tried vDSO as a part of getting rid of
Note that the f220: 48 8b 44 24 10 mov 0x10(%rsp),%rax
f225: 31 ff xor %edi,%edi
f227: 4c 89 fe mov %r15,%rsi
f22a: ff d0 callq *%rax
f22c: 85 c0 test %eax,%eax
f22e: 75 6f jne f29f <_ZN17system_time_bench20bench_vdso_cgt_clock17h9420e0afd8f9d31cE+0xef>
f230: 48 ff c3 inc %rbx
f233: 48 8b 04 24 mov (%rsp),%rax
f237: 8b 4c 24 08 mov 0x8(%rsp),%ecx
f23b: 48 89 04 24 mov %rax,(%rsp)
f23f: 89 4c 24 08 mov %ecx,0x8(%rsp)
f243: 4c 39 e3 cmp %r12,%rbx
f246: 72 d8 jb f220 <_ZN17system_time_bench20bench_vdso_cgt_clock17h9420e0afd8f9d31cE+0x70> ...which gives a fairly good idea on what is actually measured. So in any case, they are almost identical in run time. But how is this possible? The CloudFlare post mentions 2x speedup over the system call... And I realized that I was actually measuring the For the curiosity I've also benchmarked against musl. In my understanding musl also does vDSO for
...exactly showing that fact. Takeaway: As long as we are using a common libc (which includes glibc and musl), we automatically get vDSO. There indeed is a slight benefit in using vDSO PS. During doing this, I've also confirmed that macOS PPS. I guess that |
Formatting also seems slow. I tested the #[bench]
fn chrono_format(bench: &mut Bencher) {
let ts = Local.timestamp(100, 100);
bench.iter(|| format!("{}", ts.format("%F %T")))
}
#[bench]
fn manual_format(bench: &mut Bencher) {
let ts = Local.timestamp(100, 100);
bench.iter(|| {
format!(
"{}-{:02}-{:02} {:02}:{:02}:{:02}",
ts.year(),
ts.month(),
ts.day(),
ts.hour(),
ts.minute(),
ts.second()
)
})
} With these results:
Can |
I'm sure it can. The formatting/parsing infrastructure is complex. I am currently significantly more interested in improving error messages than in improving speed, so while benchmarks and optimizations would be very welcome I wouldn't be super interested in taking things that make them both worse. On the other hand, I'm also interested in basically completely rewriting the parsing (and therefore formatting) code, specifically because of the fact that errors are pretty opaque right now, so optimizations are welcome because they might inform a new design. If you (or anyone) want to work on formatting/parsing performance I'm happy to mentor, but it is pretty low on my priority list of my personal work right now. |
Working on
slog-rs
- a logger, I've been doing some benchmarking, and getting a current timestamp (formatted) from chrono is taking a lot of time.Fist I've discovered that just taking time (without formatting) takes around 60ns in my benchmarks. Does it require doing two syscalls (one for time, one for timezone)? I've filled rust-lang/rust#36358 to inquire why it isn't faster.
Second formatting is taking around 500ns, which seems too much. I wish formatting provided something like
fn fmt_rfc3339<W : io::Write>(&self, io : W) -> io::Result<()>
which does not require any allocation. Also, when investigating the code, it seems there's a lot ofcloned()
calls, and the whole thing is based onStrftimeItems
which likeprintf
in C: scans the format every time.The text was updated successfully, but these errors were encountered: