mirror of
https://github.com/openharmony/third_party_rust_unicode-bidi.git
synced 2026-07-01 21:24:00 -04:00
Instrumentation for perf analysis using Flame
* [Cargo.toml] Add `flame_it` feature to enable instrumentation in `lib.rs` and on `pub fn`s on major modules. * Add example crate to get bidi info and visual runs for one piece of bidi text and output flame chart. * Move UDHR data files out of `/benches/` and into `/data/` to share between various types of crates in the repo. Test: ``` cargo run --example flame_udhr --features flame_it ``` produces `flame-udhr-graph.html`..
This commit is contained in:
+14
-6
@@ -1,5 +1,7 @@
|
||||
language: rust
|
||||
sudo: false
|
||||
os: linux
|
||||
dist: trusty
|
||||
|
||||
rust:
|
||||
- nightly
|
||||
@@ -17,12 +19,18 @@ notifications:
|
||||
email:
|
||||
on_success: never
|
||||
|
||||
before_script:
|
||||
- pip install git+https://github.com/euclio/travis-cargo@kcov --user && export PATH=$HOME/.local/bin:$PATH
|
||||
|
||||
script:
|
||||
- cargo build --verbose
|
||||
- cargo test --verbose
|
||||
- cargo test --verbose --features with_serde
|
||||
- cargo doc --verbose --no-deps
|
||||
- travis-cargo bench
|
||||
|
||||
- RUST_BACKTRACE=1 cargo test --verbose
|
||||
- RUST_BACKTRACE=1 cargo test --verbose --features with_serde
|
||||
|
||||
- if [ "$TRAVIS_RUST_VERSION" != "nightly" ] ; then exit ; fi
|
||||
|
||||
- RUST_BACKTRACE=1 cargo test --verbose --features bench_it
|
||||
- RUST_BACKTRACE=1 cargo test --verbose --features flame_it
|
||||
|
||||
- cargo run --verbose --features flame_it --example flame_udhr
|
||||
|
||||
- cargo bench --verbose --features bench_it
|
||||
|
||||
+5
-1
@@ -14,6 +14,8 @@ exclude = ["*.txt"]
|
||||
name = "unicode_bidi"
|
||||
|
||||
[dependencies]
|
||||
flame = { version = "0.1", optional = true }
|
||||
flamer = { version = "0.1", optional = true }
|
||||
matches = "0.1"
|
||||
serde = {version = ">=0.8, <2.0", optional = true}
|
||||
serde_derive = {version = ">=0.8, <2.0", optional = true}
|
||||
@@ -23,5 +25,7 @@ serde_test = ">=0.8, <2.0"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
unstable = [] # Use in benches/
|
||||
unstable = [] # travis-cargo needs it
|
||||
bench_it = []
|
||||
flame_it = ["flame", "flamer"]
|
||||
with_serde = ["serde", "serde_derive"]
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![cfg(all(test, feature = "unstable"))]
|
||||
#![cfg(all(test, feature = "bench_it"))]
|
||||
#![feature(test)]
|
||||
|
||||
extern crate test;
|
||||
|
||||
+25
-25
@@ -7,7 +7,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![cfg(all(test, feature = "unstable"))]
|
||||
#![cfg(all(test, feature = "bench_it"))]
|
||||
#![feature(test)]
|
||||
|
||||
extern crate test;
|
||||
@@ -19,33 +19,33 @@ use unicode_bidi::BidiInfo;
|
||||
|
||||
|
||||
const LTR_TEXTS: &[&str] = &[
|
||||
include_str!("udhr_data/ltr/udhr_acu_1.txt"),
|
||||
include_str!("udhr_data/ltr/udhr_auc.txt"),
|
||||
include_str!("udhr_data/ltr/udhr_eng.txt"),
|
||||
include_str!("udhr_data/ltr/udhr_knc.txt"),
|
||||
include_str!("udhr_data/ltr/udhr_krl.txt"),
|
||||
include_str!("udhr_data/ltr/udhr_lot.txt"),
|
||||
include_str!("udhr_data/ltr/udhr_mly_latn.txt"),
|
||||
include_str!("udhr_data/ltr/udhr_piu.txt"),
|
||||
include_str!("udhr_data/ltr/udhr_qug.txt"),
|
||||
include_str!("udhr_data/ltr/udhr_snn.txt"),
|
||||
include_str!("udhr_data/ltr/udhr_tiv.txt"),
|
||||
include_str!("udhr_data/ltr/udhr_uig_latn.txt"),
|
||||
include_str!("../data/udhr/ltr/udhr_acu_1.txt"),
|
||||
include_str!("../data/udhr/ltr/udhr_auc.txt"),
|
||||
include_str!("../data/udhr/ltr/udhr_eng.txt"),
|
||||
include_str!("../data/udhr/ltr/udhr_knc.txt"),
|
||||
include_str!("../data/udhr/ltr/udhr_krl.txt"),
|
||||
include_str!("../data/udhr/ltr/udhr_lot.txt"),
|
||||
include_str!("../data/udhr/ltr/udhr_mly_latn.txt"),
|
||||
include_str!("../data/udhr/ltr/udhr_piu.txt"),
|
||||
include_str!("../data/udhr/ltr/udhr_qug.txt"),
|
||||
include_str!("../data/udhr/ltr/udhr_snn.txt"),
|
||||
include_str!("../data/udhr/ltr/udhr_tiv.txt"),
|
||||
include_str!("../data/udhr/ltr/udhr_uig_latn.txt"),
|
||||
];
|
||||
|
||||
const BIDI_TEXTS: &[&str] = &[
|
||||
include_str!("udhr_data/bidi/udhr_aii.txt"),
|
||||
include_str!("udhr_data/bidi/udhr_arb.txt"),
|
||||
include_str!("udhr_data/bidi/udhr_mly_arab.txt"),
|
||||
include_str!("udhr_data/bidi/udhr_pes_1.txt"),
|
||||
include_str!("udhr_data/bidi/udhr_skr.txt"),
|
||||
include_str!("udhr_data/bidi/udhr_urd.txt"),
|
||||
include_str!("udhr_data/bidi/udhr_pes_2.txt"),
|
||||
include_str!("udhr_data/bidi/udhr_uig_arab.txt"),
|
||||
include_str!("udhr_data/bidi/udhr_urd_2.txt"),
|
||||
include_str!("udhr_data/bidi/udhr_heb.txt"),
|
||||
include_str!("udhr_data/bidi/udhr_pnb.txt"),
|
||||
include_str!("udhr_data/bidi/udhr_ydd.txt"),
|
||||
include_str!("../data/udhr/bidi/udhr_aii.txt"),
|
||||
include_str!("../data/udhr/bidi/udhr_arb.txt"),
|
||||
include_str!("../data/udhr/bidi/udhr_mly_arab.txt"),
|
||||
include_str!("../data/udhr/bidi/udhr_pes_1.txt"),
|
||||
include_str!("../data/udhr/bidi/udhr_skr.txt"),
|
||||
include_str!("../data/udhr/bidi/udhr_urd.txt"),
|
||||
include_str!("../data/udhr/bidi/udhr_pes_2.txt"),
|
||||
include_str!("../data/udhr/bidi/udhr_uig_arab.txt"),
|
||||
include_str!("../data/udhr/bidi/udhr_urd_2.txt"),
|
||||
include_str!("../data/udhr/bidi/udhr_heb.txt"),
|
||||
include_str!("../data/udhr/bidi/udhr_pnb.txt"),
|
||||
include_str!("../data/udhr/bidi/udhr_ydd.txt"),
|
||||
];
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright 2017 The Servo Project Developers. See the
|
||||
// COPYRIGHT file at the top-level directory of this distribution.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
//! Profiling example
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
#![cfg_attr(feature="flame_it", feature(plugin, custom_attribute))]
|
||||
#![cfg_attr(feature="flame_it", plugin(flamer))]
|
||||
|
||||
|
||||
#[cfg(feature = "flame_it")]
|
||||
extern crate flame;
|
||||
|
||||
extern crate unicode_bidi;
|
||||
|
||||
|
||||
use std::fs::File;
|
||||
|
||||
use unicode_bidi::BidiInfo;
|
||||
|
||||
|
||||
#[cfg(feature = "flame_it")]
|
||||
fn main() {
|
||||
const BIDI_TEXT: &'static str = include_str!("../data/udhr/bidi/udhr_pes_1.txt");
|
||||
|
||||
flame::start("main(): BidiInfo::new()");
|
||||
let bidi_info = BidiInfo::new(BIDI_TEXT, None);
|
||||
flame::end("main(): BidiInfo::new()");
|
||||
|
||||
flame::start("main(): iter bidi_info.paragraphs");
|
||||
for para in &bidi_info.paragraphs {
|
||||
let line = para.range.clone();
|
||||
bidi_info.reorder_line(para, line);
|
||||
}
|
||||
flame::end("main(): iter bidi_info.paragraphs");
|
||||
|
||||
flame::dump_html(&mut File::create("flame-udhr-graph.html").unwrap()).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "flame_it"))]
|
||||
// Allow example to compile
|
||||
fn main() {}
|
||||
@@ -20,6 +20,7 @@ use BidiClass::*;
|
||||
///
|
||||
/// `processing_classes[i]` must contain the `BidiClass` of the char at byte index `i`,
|
||||
/// for each char in `text`.
|
||||
#[cfg_attr(feature="flame_it", flame)]
|
||||
pub fn compute(
|
||||
text: &str,
|
||||
para_level: Level,
|
||||
|
||||
@@ -20,6 +20,7 @@ use BidiClass::*;
|
||||
/// 3.3.4 Resolving Weak Types
|
||||
///
|
||||
/// http://www.unicode.org/reports/tr9/#Resolving_Weak_Types
|
||||
#[cfg_attr(feature="flame_it", flame)]
|
||||
pub fn resolve_weak(sequence: &IsolatingRunSequence, processing_classes: &mut [BidiClass]) {
|
||||
// FIXME (#8): This function applies steps W1-W6 in a single pass. This can produce
|
||||
// incorrect results in cases where a "later" rule changes the value of `prev_class` seen
|
||||
@@ -134,6 +135,7 @@ pub fn resolve_weak(sequence: &IsolatingRunSequence, processing_classes: &mut [B
|
||||
/// 3.3.5 Resolving Neutral Types
|
||||
///
|
||||
/// http://www.unicode.org/reports/tr9/#Resolving_Neutral_Types
|
||||
#[cfg_attr(feature="flame_it", flame)]
|
||||
pub fn resolve_neutral(
|
||||
sequence: &IsolatingRunSequence,
|
||||
levels: &[Level],
|
||||
@@ -198,6 +200,7 @@ pub fn resolve_neutral(
|
||||
/// Returns the maximum embedding level in the paragraph.
|
||||
///
|
||||
/// http://www.unicode.org/reports/tr9/#Resolving_Implicit_Levels
|
||||
#[cfg_attr(feature="flame_it", flame)]
|
||||
pub fn resolve_levels(original_classes: &[BidiClass], levels: &mut [Level]) -> Level {
|
||||
let mut max_level = Level::ltr();
|
||||
|
||||
|
||||
+35
@@ -57,6 +57,10 @@
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
#![cfg_attr(feature="flame_it", feature(plugin, custom_attribute))]
|
||||
#![cfg_attr(feature="flame_it", plugin(flamer))]
|
||||
|
||||
|
||||
#[macro_use]
|
||||
extern crate matches;
|
||||
|
||||
@@ -67,6 +71,10 @@ extern crate serde_derive;
|
||||
#[cfg(all(feature = "with_serde", test))]
|
||||
extern crate serde_test;
|
||||
|
||||
#[cfg(feature="flame_it")]
|
||||
extern crate flame;
|
||||
|
||||
|
||||
pub mod deprecated;
|
||||
pub mod format_chars;
|
||||
pub mod level;
|
||||
@@ -127,6 +135,7 @@ impl<'text> InitialInfo<'text> {
|
||||
/// Also sets the class for each First Strong Isolate initiator (FSI) to LRI or RLI if a strong
|
||||
/// character is found before the matching PDI. If no strong character is found, the class will
|
||||
/// remain FSI, and it's up to later stages to treat these as LRI when needed.
|
||||
#[cfg_attr(feature="flame_it", flame)]
|
||||
pub fn new(text: &str, default_para_level: Option<Level>) -> InitialInfo {
|
||||
let mut original_classes = Vec::with_capacity(text.len());
|
||||
|
||||
@@ -137,10 +146,22 @@ impl<'text> InitialInfo<'text> {
|
||||
let mut para_start = 0;
|
||||
let mut para_level = default_para_level;
|
||||
|
||||
#[cfg(feature="flame_it")]
|
||||
flame::start("InitialInfo::new(): iter text.char_indices()");
|
||||
|
||||
for (i, c) in text.char_indices() {
|
||||
let class = bidi_class(c);
|
||||
|
||||
#[cfg(feature="flame_it")]
|
||||
flame::start("original_classes.extend()");
|
||||
|
||||
original_classes.extend(repeat(class).take(c.len_utf8()));
|
||||
|
||||
#[cfg(feature="flame_it")]
|
||||
flame::end("original_classes.extend()");
|
||||
|
||||
match class {
|
||||
|
||||
B => {
|
||||
// P1. Split the text into separate paragraphs. The paragraph separator is kept
|
||||
// with the previous paragraph.
|
||||
@@ -158,6 +179,7 @@ impl<'text> InitialInfo<'text> {
|
||||
para_level = default_para_level;
|
||||
isolate_stack.clear();
|
||||
}
|
||||
|
||||
L | R | AL => {
|
||||
match isolate_stack.last() {
|
||||
Some(&start) => {
|
||||
@@ -170,6 +192,7 @@ impl<'text> InitialInfo<'text> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None => {
|
||||
if para_level.is_none() {
|
||||
// P2. Find the first character of type L, AL, or R, while skipping
|
||||
@@ -180,12 +203,15 @@ impl<'text> InitialInfo<'text> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RLI | LRI | FSI => {
|
||||
isolate_stack.push(i);
|
||||
}
|
||||
|
||||
PDI => {
|
||||
isolate_stack.pop();
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -197,6 +223,9 @@ impl<'text> InitialInfo<'text> {
|
||||
}
|
||||
assert_eq!(original_classes.len(), text.len());
|
||||
|
||||
#[cfg(feature="flame_it")]
|
||||
flame::end("InitialInfo::new(): iter text.char_indices()");
|
||||
|
||||
InitialInfo {
|
||||
text: text,
|
||||
original_classes: original_classes,
|
||||
@@ -236,6 +265,7 @@ impl<'text> BidiInfo<'text> {
|
||||
/// text that is entirely LTR. See the `nsBidi` class from Gecko for comparison.
|
||||
///
|
||||
/// TODO: Support auto-RTL base direction
|
||||
#[cfg_attr(feature="flame_it", flame)]
|
||||
pub fn new(text: &str, default_para_level: Option<Level>) -> BidiInfo {
|
||||
let InitialInfo {
|
||||
original_classes,
|
||||
@@ -283,6 +313,7 @@ impl<'text> BidiInfo<'text> {
|
||||
|
||||
/// Re-order a line based on resolved levels and return only the embedding levels, one `Level`
|
||||
/// per *byte*.
|
||||
#[cfg_attr(feature="flame_it", flame)]
|
||||
pub fn reordered_levels(&self, para: &ParagraphInfo, line: Range<usize>) -> Vec<Level> {
|
||||
let (levels, _) = self.visual_runs(para, line.clone());
|
||||
levels
|
||||
@@ -290,6 +321,7 @@ impl<'text> BidiInfo<'text> {
|
||||
|
||||
/// Re-order a line based on resolved levels and return only the embedding levels, one `Level`
|
||||
/// per *character*.
|
||||
#[cfg_attr(feature="flame_it", flame)]
|
||||
pub fn reordered_levels_per_char(
|
||||
&self,
|
||||
para: &ParagraphInfo,
|
||||
@@ -301,6 +333,7 @@ impl<'text> BidiInfo<'text> {
|
||||
|
||||
|
||||
/// Re-order a line based on resolved levels and return the line in display order.
|
||||
#[cfg_attr(feature="flame_it", flame)]
|
||||
pub fn reorder_line(&self, para: &ParagraphInfo, line: Range<usize>) -> Cow<'text, str> {
|
||||
let (levels, runs) = self.visual_runs(para, line.clone());
|
||||
|
||||
@@ -325,6 +358,7 @@ impl<'text> BidiInfo<'text> {
|
||||
/// `line` is a range of bytes indices within `levels`.
|
||||
///
|
||||
/// http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels
|
||||
#[cfg_attr(feature="flame_it", flame)]
|
||||
pub fn visual_runs(
|
||||
&self,
|
||||
para: &ParagraphInfo,
|
||||
@@ -449,6 +483,7 @@ impl<'text> BidiInfo<'text> {
|
||||
///
|
||||
/// The levels assigned to these characters are not specified by the algorithm. This function
|
||||
/// assigns each one the level of the previous character, to avoid breaking level runs.
|
||||
#[cfg_attr(feature="flame_it", flame)]
|
||||
fn assign_levels_to_removed_chars(para_level: Level, classes: &[BidiClass], levels: &mut [Level]) {
|
||||
for i in 0..levels.len() {
|
||||
if prepare::removed_by_x9(classes[i]) {
|
||||
|
||||
@@ -41,6 +41,7 @@ pub struct IsolatingRunSequence {
|
||||
/// whose matching PDI is the first character of the next level run in the sequence.
|
||||
///
|
||||
/// Note: This function does *not* return the sequences in order by their first characters.
|
||||
#[cfg_attr(feature="flame_it", flame)]
|
||||
pub fn isolating_run_sequences(
|
||||
para_level: Level,
|
||||
original_classes: &[BidiClass],
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![cfg(all(test, not(feature = "unstable")))]
|
||||
#![cfg(test)]
|
||||
|
||||
extern crate unicode_bidi;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user