-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add chained fallback support and performance improved (#69)
* Add more than one fallback with priority support Example: i18n!("locales", fallback = ["en", "es]); * Add more than on fallback testing * Add new proc_macro key! support * Add new lock-free AtomicStr * Remove RwLock from locale() and set_locale() * Use AtomicStr instead of RwLock<String> * Change locale() return type to Arc<String> * tests/locales/en.yml: Add lorem ipsum long text item * bench: Add t_with_threads and t_lorem_ipsum * bench: Add t_with_args (many) * Add new function `replace_patterns()` to speed up string replacement * Use `replace_patterns()` in t! to speed up string replacement * Change _rust_i18n_translate() return type to Cow<str> to reduce string copy * Fix some testing compile errors * Change `t!()` with patterns return type to Cow::Owned(String) * Fix examples compile error * Early return in fallback parsing to avoid an 'else' clause * README.md: Update benchmark results
- Loading branch information
Showing
16 changed files
with
303 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,26 @@ fn bench_t(c: &mut Criterion) { | |
|
||
c.bench_function("t_with_locale", |b| b.iter(|| t!("hello", locale = "en"))); | ||
|
||
c.bench_function("t_with_threads", |b| { | ||
let exit_loop = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)); | ||
let mut handles = Vec::new(); | ||
for _ in 0..4 { | ||
let exit_loop = exit_loop.clone(); | ||
handles.push(std::thread::spawn(move || { | ||
while !exit_loop.load(std::sync::atomic::Ordering::SeqCst) { | ||
criterion::black_box(t!("hello")); | ||
} | ||
})); | ||
} | ||
b.iter(|| t!("hello")); | ||
exit_loop.store(true, std::sync::atomic::Ordering::SeqCst); | ||
for handle in handles { | ||
handle.join().unwrap(); | ||
} | ||
}); | ||
|
||
c.bench_function("t_lorem_ipsum", |b| b.iter(|| t!("lorem-ipsum"))); | ||
|
||
// 73.239 ns | ||
c.bench_function("_rust_i18n_translate", |b| { | ||
b.iter(|| crate::_rust_i18n_translate("en", "hello")) | ||
|
@@ -44,6 +64,21 @@ fn bench_t(c: &mut Criterion) { | |
c.bench_function("t_with_args (str)", |b| { | ||
b.iter(|| t!("a.very.nested.message", "name" = "Jason", "msg" = "Bla bla")) | ||
}); | ||
|
||
c.bench_function("t_with_args (many)", |b| { | ||
b.iter(|| { | ||
t!( | ||
"a.very.nested.response", | ||
id = 123, | ||
name = "Marion", | ||
surname = "Christiansen", | ||
email = "[email protected]", | ||
city = "Litteltown", | ||
zip = 8408, | ||
website = "https://snoopy-napkin.name" | ||
) | ||
}) | ||
}); | ||
} | ||
|
||
criterion_group!(benches, bench_t); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
use std::fmt; | ||
use std::sync::atomic::{AtomicPtr, Ordering}; | ||
use std::sync::Arc; | ||
|
||
/// A thread-safe atomically reference-counting string. | ||
pub struct AtomicStr(AtomicPtr<String>); | ||
|
||
impl AtomicStr { | ||
/// Create a new `AtomicStr` with the given value. | ||
pub fn new(value: impl Into<String>) -> Self { | ||
let arced = Arc::new(value.into()); | ||
Self(AtomicPtr::new(Arc::into_raw(arced) as _)) | ||
} | ||
|
||
/// Get the string slice. | ||
pub fn as_str(&self) -> &str { | ||
unsafe { | ||
let arced_ptr = self.0.load(Ordering::SeqCst); | ||
assert!(!arced_ptr.is_null()); | ||
&*arced_ptr | ||
} | ||
} | ||
|
||
/// Get the cloned inner `Arc<String>`. | ||
pub fn clone_string(&self) -> Arc<String> { | ||
unsafe { | ||
let arced_ptr = self.0.load(Ordering::SeqCst); | ||
assert!(!arced_ptr.is_null()); | ||
Arc::increment_strong_count(arced_ptr); | ||
Arc::from_raw(arced_ptr) | ||
} | ||
} | ||
|
||
/// Replaces the value at self with src, returning the old value, without dropping either. | ||
pub fn replace(&self, src: impl Into<String>) -> Arc<String> { | ||
unsafe { | ||
let arced_new = Arc::new(src.into()); | ||
let arced_old_ptr = self.0.swap(Arc::into_raw(arced_new) as _, Ordering::SeqCst); | ||
assert!(!arced_old_ptr.is_null()); | ||
Arc::from_raw(arced_old_ptr) | ||
} | ||
} | ||
} | ||
|
||
impl Drop for AtomicStr { | ||
fn drop(&mut self) { | ||
unsafe { | ||
let arced_ptr = self.0.swap(std::ptr::null_mut(), Ordering::SeqCst); | ||
assert!(!arced_ptr.is_null()); | ||
let _ = Arc::from_raw(arced_ptr); | ||
} | ||
} | ||
} | ||
|
||
impl AsRef<str> for AtomicStr { | ||
fn as_ref(&self) -> &str { | ||
self.as_str() | ||
} | ||
} | ||
|
||
impl<T> From<T> for AtomicStr | ||
where | ||
T: Into<String>, | ||
{ | ||
fn from(value: T) -> Self { | ||
Self::new(value) | ||
} | ||
} | ||
|
||
impl From<&AtomicStr> for Arc<String> { | ||
fn from(value: &AtomicStr) -> Self { | ||
value.clone_string() | ||
} | ||
} | ||
|
||
impl fmt::Display for AtomicStr { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
write!(f, "{}", self.as_str()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.