-
러스트에서 문자열을 효과적으로 연결하기Programmer/Programming 2019. 2. 8. 17:41
러스트(rust)에서 문자열을(&String or &str)을 연결(concatenation)하는 방법에는 여러가지가 있다.
- SliceConcatExt::concat() -> String
- SliceConcatExt::join(sep: &str) -> String
- Add::add(rhs: &str) -> String
- String::push_str(string: &str) -> String
- write! and writteln! macros
SliceConcatExt::concat() -> String
문자열의 슬라이스(slice)에서 concat() 메서드를 호출하면 각 요소를 연결한 문자열을 생성한다.
SliceConcatExt::join(sep: &str) -> String
각 문자열 요소 사이에 지정된 구분 기호를 사용하여 문자열 배열의 모든 요소를 연결하는 함수다.
우리는 모든 문자열을 단순 연결할 예정임으로 빈 문자열을 전달한다.다음 두가지는 String 메서드를 사용하여 문자열을 합칠 예정이다.
러스트에서 mut 키워드가 붙은 String은 자바(Java)의 StringBuilder와 비슷하다.Add::add(rhs: &str) -> String
String은 '+' 연산자를 오버로딩(overloading)하는 Add 트레이트(trait)를 구현하였다.
String의 '+'는 자신의 뒤에 rhs를 추가하는 기능을 한다.String::push_str(string: &str) -> String
String은 '+' 연산자와 동일한 역활을 한다.
write!와 writeln! 매크로는 강력한 편리함을 제공하는 방식이다.
use std::fmt::Write; let mut bld = String::new(); writeln!(bld, "{} and {} are designed for writing to output stream.", "write!", "writeln!").unwarp(); writeln!(bld, "They can append formatted text").unwrap();
이 4가지 방법의 성능을 측정해보았다.
마지막 두 개는 String::with_capacity(size: usize)를 사용하여 충분한 크기로 String을 생성한 뒤에 문자열을 연결했다.
결과는 다음과 같다.(상대적인 차이만 보자)방법
결과
설명
SliceConcatExt::concat()
443 ns/iter (+/- 62)
SliceConcatExt::join(sep: &str)
459 ns/iter (+/- 49)
매 요소마다 구분 기호를 추가함
Add::add(rhs: &str)
1,078 ns/iter (+/- 106)
String::push_str(string: &str)
1,159 ns/iter (+/- 128)
위와 마찬가지
Add::add(rhs: &str) with capacity
621 ns/iter (+/- 110) 버퍼를 늘려야 하는 오버헤드 없음
String::push_str(string: &str) with capacity 598 ns/iter (+/- 92) 위와 마찮가지
write! and writeln! macro 2,676 ns/iter (+/- 361) 매번 포맷 문자 확장이 필요함
정리하면
- 성능에 매우 민감하지 않으면 write!와 writeln! 매크로는 정말 편하다.
- 성능이 매우 중요하면 SliceConcatExt::concat() 사용한다.
- 문자열 요소 사이에 지정된 구분 기호가 필요하면 SliceConcatExt::join(sep: &str) 더 낫다.
- Add::add(rhs: &str), String::push_str(string: &str) 사용할 때, 크기를 어느정도 예측할 수 있다면, 충분한 크기로 String을 생성한다.
- 연결할 문자열을 언제까지 받을지 예측이 안되는 경우에는 Add::add(rhs: &str), String::push_str(string: &str)를 사용한다. Vec<String>이 너무 많은 메모리를 사용할 수 있다. 2 3
- 일반적으로 현재 크기의 두배로 늘림 [본문으로]
- 예를 들면, 네트워크를 통해 받을 때 [본문으로]
- 한국 러스트 컴뮤티니의 @Kroisse님이 알려줌.
일반적으로는 concat()이나 push_str() 중에 아무것이나 사용해도 무방하다.
성능에 영향을 줄 정도로 양이 늘어나면 https://crates.io/crates/ropey 사용을 고려한다. [본문으로]
'Programmer > Programming' 카테고리의 다른 글
러스트(Rust)를 위한 SyntaxHighlighter 3.0 플러그인 개선 (0) 2019.02.14 러스트와 다른 언어의 멀티라인 처리 비교 (0) 2019.02.12 파이썬 프러퍼티 사용하여 일관되게 속성에 접근하라 (0) 2018.01.17 기본 값(default value)을 언제 사용할까? (0) 2018.01.02 C++에서 언제 어떻게 struct를 사용하는가? (4) 2017.09.25 댓글