Skip to content

Commit

Permalink
perf: use memory efficient char counting
Browse files Browse the repository at this point in the history
  • Loading branch information
funbiscuit committed Jan 21, 2024
1 parent f73acc6 commit 8ac109a
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 14 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


[Demo](examples/arduino/README.md) of CLI running on Arduino Nano.
Memory usage: 17KiB ROM, 500B static RAM. Most of static RAM is used by help strings.
Memory usage: 15KiB of ROM and 0.5KiB of static RAM. Most of static RAM is used by help strings.

![Arduino Demo](examples/arduino/demo.gif)

Expand Down
5 changes: 2 additions & 3 deletions embedded-cli/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl<B: Buffer> Editor<B> {

pub fn insert(&mut self, text: &str) -> Option<&str> {
let remaining = self.buffer.len() - self.valid;
let chars = text.chars().count();
let chars = utils::char_count(text);
let text = text.as_bytes();
if remaining < text.len() {
//TODO: try to grow buffer
Expand All @@ -118,8 +118,7 @@ impl<B: Buffer> Editor<B> {
}

pub fn len(&self) -> usize {
//TODO: use another usize to store len
self.text().chars().count()
utils::char_count(self.text())
}

pub fn move_left(&mut self) -> bool {
Expand Down
18 changes: 18 additions & 0 deletions embedded-cli/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ pub fn char_byte_index(text: &str, char_index: usize) -> Option<usize> {
None
}

pub fn char_count(text: &str) -> usize {
let mut accum = Utf8Accum::default();
let mut count = 0;
for &b in text.as_bytes() {
if accum.push_byte(b).is_some() {
count += 1;
}
}
count
}

/// Function to rotate `buf` by `mid` elements
///
/// Not using `core::slice::rotate_left` since it
Expand Down Expand Up @@ -112,4 +123,11 @@ mod tests {
assert_eq!(utils::char_byte_index(text, pos), expected)
}
}

#[rstest]
#[case("abcdef")]
#[case("abcd абв 佐佗佟𑿁 𑿆𑿌")]
fn char_count(#[case] text: &str) {
assert_eq!(utils::char_count(text), text.chars().count())
}
}
20 changes: 10 additions & 10 deletions examples/arduino/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This example shows how to build cli with Arduino Nano.
Another Arduino can also be used, but you will have to tweak configs.
Example uses ~17KiB of ROM and ~0.5KiB of static RAM.
Example uses ~15KiB of ROM and ~0.5KiB of static RAM.
Most of RAM is taken by derived implementations for help and autocomplete
that don't use progmem. In future this should be fixed.

Expand All @@ -23,7 +23,7 @@ tio /dev/ttyUSB0 --map ODELBS

# Memory usage

Memory usage might vary depending on compiler version and build environment.
Memory usage might vary depending on compiler version, build environment and library version.
To find out total ROM usage run:

```shell
Expand All @@ -33,13 +33,13 @@ cargo bloat --release
Example output:
```
File .text Size Crate Name
1.7% 52.5% 8.7KiB arduino_cli arduino_cli::__avr_device_rt_main
0.2% 7.5% 1.3KiB core <core::iter::adapters::skip::Skip<I> as core::iter::traits::iterator::Iterator>::next
0.2% 6.0% 1016B embedded_cli embedded_cli::autocomplete::Autocompletion::merge_autocompletion
0.1% 4.3% 738B embedded_cli embedded_cli::token::Tokens::remove
0.1% 3.2% 538B embedded_cli embedded_cli::token::Tokens::new
0.8% 23.7% 3.9KiB And 27 smaller methods. Use -n N to show more.
3.2% 100.0% 16.6KiB .text section size, the file size is 517.3KiB
1.6% 54.5% 8.1KiB arduino_cli arduino_cli::try_run
0.2% 6.7% 1016B embedded_cli embedded_cli::autocomplete::Autocompletion::merge_autocompletion
0.1% 3.6% 538B embedded_cli embedded_cli::token::Tokens::new
0.1% 3.5% 530B embedded_cli embedded_cli::help::HelpRequest::from_tokens
0.1% 3.1% 472B embedded_cli embedded_cli::token::Tokens::remove
0.8% 25.4% 3.8KiB And 34 smaller methods. Use -n N to show more.
3.0% 100.0% 14.8KiB .text section size, the file size is 498.4KiB
```

To find total static memory usage:
Expand All @@ -54,7 +54,7 @@ cargo build --release && \

Example output:
```
RAM usage: 489
RAM usage: 506
```

To further analyze used space:
Expand Down

0 comments on commit 8ac109a

Please sign in to comment.