From 7690a4cc321f166fdf74e180825994da271b8d47 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Wed, 6 Oct 2021 19:41:44 +0900 Subject: [PATCH] single pass set repr --- vm/src/builtins/set.rs | 46 +++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/vm/src/builtins/set.rs b/vm/src/builtins/set.rs index 9fd386d795..90de9f816c 100644 --- a/vm/src/builtins/set.rs +++ b/vm/src/builtins/set.rs @@ -199,16 +199,41 @@ impl PySetInner { } fn repr(&self, class_name: Option<&str>, vm: &VirtualMachine) -> PyResult { - let mut str_parts = Vec::with_capacity(self.content.len()); + let mut repr_len = class_name.map_or(0, |name| name.len() + 2); + let mut parts = Vec::with_capacity(self.content.len()); for key in self.elements() { let part = vm.to_repr(&key)?; - str_parts.push(part.as_str().to_owned()); + repr_len += part.as_str().len() + 2; + parts.push(part); } - let inner_repr = format!("{{{}}}", str_parts.join(", ")); + let (parts, repr_len) = (parts, repr_len); + + let mut repr = String::with_capacity(repr_len); if let Some(name) = class_name { - return Ok(format!("{}({})", name, inner_repr)); - }; - Ok(inner_repr) + repr.push_str(name); + repr.push('('); + } + repr.push('{'); + { + let mut parts_iter = parts.into_iter(); + repr.push_str( + parts_iter + .next() + .expect("this is not called for empty set") + .as_str(), + ); + for part in parts_iter { + repr.push_str(", "); + repr.push_str(part.as_str()); + } + } + repr.push('}'); + if class_name.is_some() { + repr.push(')'); + } + debug_assert_eq!(repr.len(), repr_len); + + Ok(repr) } fn add(&self, item: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { @@ -480,11 +505,12 @@ impl PySet { let s = if zelf.inner.len() == 0 { format!("{}()", class_name) } else if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) { - if class_name != "set" { - zelf.inner.repr(Some(&class_name), vm)? + let name = if class_name != "set" { + Some(class_name.as_str()) } else { - zelf.inner.repr(None, vm)? - } + None + }; + zelf.inner.repr(name, vm)? } else { format!("{}(...)", class_name) };