Use Cow to avoid unnecessary allocation

This commit is contained in:
topecongiro 2017-09-15 18:11:24 +09:00
parent 0b3b89d51f
commit f0580ae91a
6 changed files with 51 additions and 30 deletions

View File

@ -9,6 +9,7 @@
// except according to those terms.
use std::cmp::{min, Ordering};
use std::borrow::Cow;
use std::fmt::Write;
use std::iter::{repeat, ExactSizeIterator};
@ -1364,10 +1365,10 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
}
}
fn rewrite_label(label: Option<ast::SpannedIdent>) -> String {
fn rewrite_label(label: Option<ast::SpannedIdent>) -> Cow<'static, str> {
match label {
Some(ident) => format!("{}: ", ident.node),
None => "".to_owned(),
Some(ident) => Cow::from(format!("{}: ", ident.node)),
None => Cow::from(""),
}
}
@ -1926,7 +1927,11 @@ fn rewrite_string_lit(context: &RewriteContext, span: Span, shape: Shape) -> Opt
string_lit
.lines()
.map(|line| {
new_indent.to_string(context.config) + line.trim_left()
format!(
"{}{}",
new_indent.to_string(context.config),
line.trim_left()
)
})
.collect::<Vec<_>>()
.join("\n")

View File

@ -24,6 +24,7 @@
extern crate term;
extern crate unicode_segmentation;
use std::borrow::Cow;
use std::collections::HashMap;
use std::fmt;
use std::io::{self, stdout, Write};
@ -247,6 +248,10 @@ pub struct Indent {
pub alignment: usize,
}
// INDENT_BUFFER.len() == 60
const INDENT_BUFFER: &str = " ";
const INDENT_BUFFER_LEN: usize = 60;
impl Indent {
pub fn new(block_indent: usize, alignment: usize) -> Indent {
Indent {
@ -294,21 +299,25 @@ pub fn width(&self) -> usize {
self.block_indent + self.alignment
}
pub fn to_string(&self, config: &Config) -> String {
pub fn to_string(&self, config: &Config) -> Cow<'static, str> {
let (num_tabs, num_spaces) = if config.hard_tabs() {
(self.block_indent / config.tab_spaces(), self.alignment)
} else {
(0, self.width())
};
let num_chars = num_tabs + num_spaces;
let mut indent = String::with_capacity(num_chars);
for _ in 0..num_tabs {
indent.push('\t')
if num_tabs == 0 && num_chars <= INDENT_BUFFER_LEN {
Cow::from(&INDENT_BUFFER[..num_chars])
} else {
let mut indent = String::with_capacity(num_chars);
for _ in 0..num_tabs {
indent.push('\t')
}
for _ in 0..num_spaces {
indent.push(' ')
}
Cow::from(indent)
}
for _ in 0..num_spaces {
indent.push(' ')
}
indent
}
}
@ -524,13 +533,13 @@ fn msg_prefix(&self) -> &str {
}
}
fn msg_suffix(&self) -> String {
fn msg_suffix(&self) -> &str {
match self.kind {
ErrorKind::LineOverflow(..) if self.is_comment => String::from(
ErrorKind::LineOverflow(..) if self.is_comment => {
"use `error_on_line_overflow_comments = false` to suppress \
the warning against line comments\n",
),
_ => String::from(""),
the warning against line comments\n"
}
_ => "",
}
}

View File

@ -289,7 +289,7 @@ pub fn write_list<I, T>(items: I, formatting: &ListFormatting) -> Option<String>
inner_item.as_ref()
};
let mut item_last_line_width = item_last_line.len() + item_sep_len;
if item_last_line.starts_with(indent_str) {
if item_last_line.starts_with(&**indent_str) {
item_last_line_width -= indent_str.len();
}

View File

@ -383,7 +383,7 @@ fn indent_macro_snippet(
.checked_sub(min_prefix_space_width)
.unwrap_or(0);
let new_indent = Indent::from_width(context.config, new_indent_width);
new_indent.to_string(context.config) + line.trim()
format!("{}{}", new_indent.to_string(context.config), line.trim())
}
None => String::new(),
})

View File

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::borrow::Cow;
use {Indent, Shape};
use comment::{rewrite_comment, CodeCharKind, CommentCodeSlices};
use config::WriteMode;
@ -118,18 +120,23 @@ fn write_snippet_inner<F>(
let file_name = &char_pos.file.name;
let mut cur_line = char_pos.line;
fn replace_chars(string: &str) -> String {
string
.chars()
.map(|ch| if ch.is_whitespace() { ch } else { 'X' })
.collect()
fn replace_chars<'a>(string: &'a str) -> Cow<'a, str> {
if string.contains(char::is_whitespace) {
Cow::from(
string
.chars()
.map(|ch| if ch.is_whitespace() { ch } else { 'X' })
.collect::<String>(),
)
} else {
Cow::from(string)
}
}
let replaced = match self.config.write_mode() {
let snippet = &*match self.config.write_mode() {
WriteMode::Coverage => replace_chars(old_snippet),
_ => old_snippet.to_owned(),
_ => Cow::from(old_snippet),
};
let snippet = &*replaced;
for (kind, offset, subslice) in CommentCodeSlices::new(snippet) {
debug!("{:?}: {:?}", kind, subslice);

View File

@ -89,11 +89,11 @@ pub fn format_mutability(mutability: ast::Mutability) -> &'static str {
}
#[inline]
pub fn format_abi(abi: abi::Abi, explicit_abi: bool) -> String {
pub fn format_abi(abi: abi::Abi, explicit_abi: bool) -> Cow<'static, str> {
if abi == abi::Abi::C && !explicit_abi {
"extern ".into()
Cow::from("extern ")
} else {
format!("extern {} ", abi)
Cow::from(format!("extern {} ", abi))
}
}