23년에 찾아온 특이점 중 하나는 러스트 언어를 시작했다는 것이다
파이썬을 하면서 항상 GIL이 존재해서(물론 병렬 처리를 도와주는 라이브러리들이 많지만)
멀티스레드를 직접 사용하지 못했는데, 러스트 언어를 사용해 네이티브하게 멀티스레드를 사용해볼 수 있었다.
정말 안타깝게도 티스토리에서는 코드블럭에 러스트 언어에 대한 구현이 없어 하이라이트가 제대로 들어가지 않는
단점은 덤으로 알게 되었다.
// 필요한 라이브러리와 모듈을 가져옵니다.
use std::thread;
use std::time::Instant;
fn main() {
// 데이터를 초기화합니다.
let data1 = vec![999; 1000000000];
let data2 = vec![999; 250000000];
let data3 = vec![999; 250000000];
let data4 = vec![999; 250000000];
let data5 = vec![999; 250000000];
// 단일 스레드에서 작업을 수행하고 시간을 측정합니다.
let thread_start = Instant::now();
let result1: Vec<i32> = data1
.into_iter()
.map(|i| i + 2)
.collect();
let thread_duration = thread_start.elapsed().as_secs_f32();
eprintln!("thread_duration = {:?}", thread_duration);
eprintln!("result1. = {:?}", result1.len());
// 멀티스레드에서 작업을 수행하고 시간을 측정합니다.
let multi_thread_start = Instant::now();
let handle1 = thread::spawn(| | {
let result: Vec<i32> = data2
.into_iter()
.map(|i| i + 2)
.collect();
return result
});
let handle2 = thread::spawn(|| {
let result: Vec<i32> = data3
.into_iter()
.map(|i| i + 2)
.collect();
return result
});
let handle3 = thread::spawn(|| {
let result: Vec<i32> = data4
.into_iter()
.map(|i| i + 2)
.collect();
return result
});
let handle4 = thread::spawn(|| {
let result: Vec<i32> = data5
.into_iter()
.map(|i| i + 2)
.collect();
return result
});
// 각 스레드의 결과를 수집합니다.
let result2 = handle1.join().unwrap();
let result3 = handle2.join().unwrap();
let result4 = handle3.join().unwrap();
let result5 = handle4.join().unwrap();
// 멀티스레드 작업의 총 시간을 출력합니다.
let multi_thread_duration = multi_thread_start.elapsed().as_secs_f32();
eprintln!("multi_thread_duration = {:?}", multi_thread_duration);
// 각 결과의 길이만 출력합니다 (값 사용으로 컴파일러 최적화 방지)
eprintln!("result1 = {:?}", result1.len());
eprintln!("result2 = {:?}", result2.to_owned().len());
eprintln!("result3 = {:?}", result3.to_owned().len());
eprintln!("result4 = {:?}", result4.to_owned().len());
eprintln!("result5 = {:?}", result5.to_owned().len());
}
thread의 결과는 0.678초
multi-thread의 결과는 0.263초의 결과가 나온다.
물론 시간 측정에서 데이터를 분할하는 과정에 대해서 시간을 측정하지 않아, 조금 더 효율적으로 멀티스레드가 동작하게 된 것도 있으며,
데이터의 크기가 클수록 차이가 크게 나는 경향이 있다.
추가 실험으로 Vec<i32>로 된 것을 Vec<i8>로 변경 후 작업에 임했더니
싱글스레드 7.3초
멀티스레드 5.0초의 결과값이 나오는 것을 확인했다
이는 늘어난 코드에 대비해서 그다지 효율적이지 못한 상황으로 보인다.
반응형