예전 모 회사 프로그래머가 신의 한수를 알려주겠다고 memcpy를 한번 짜보라고 하시더군요..
그래서 그냥 생각나는데요 조금 노멀하게...
char *dest8 = (char*)&dest;
char *src8 = (char*)&src;
while(--len){
*dest8++ = *src8++;
}
}
했는데, 이거 봐서 님의 경력은 얼마 안되네요 ㅋㅋ 하시더군요
ㅡ_ㅡ...
그래서 조금 고친것이
dest메모리 영역과 src메모리 영역이 겹치는지 확인하는 코드를 넣었습니다.
{
char *dest8 = (char*)dest;
char *src8 = (char*)src;
/////////////////////////////////
//dest ■■■■■ //1.dest 메모리 영역안에 src가 있거나
// src □□□□□
// dest ■■■■■ //2.src 메모리 영역안에 dest가 있으면 안됨
/////////////////////////////////
if((dest8 <= src8 //1검사
&& src8 <= dest8+len)
||(src8 <= dest8 //2검사
&& dest8 <= src8+len))
{
return false;
}
while(len--){
*dest8++ = *src8++;
}
return true;
}
뭐 여기까지 하면 그래도 안전하지 않냐라는 생각이 들었습니다만...
최근 boost 라이브러리(mpl 프로그래밍)쪽을 공부하면서 이런 방법이 나오더군요..
#include <algorithm>
#include <iterator>
#include <memory>
#include <boost/test/included/prg_exec_monitor.hpp>
#include <boost/timer.hpp>
#include <boost/type_traits.hpp>
//기존의 copy와 차별화를 위한 네임스페이스
namespace opt{
namespace detail{
//이건 직접 대입시켜서 복사하는 방식
template<typename l1, typename l2, bool b>
l2 copy_imp(l1 first, l1 last, l2 out, const boost::integral_constant<bool, b>&)
{
while(first != last){
*out = *first;
++out;
++first;
}
return out;
}
//memcpy를 이용하는 방식
template<typename T>
T* copy_imp(const T *first, const T *last, const boost::true_type&)
{
memcpy(out, first, (last-first)*sizeof(T));
return out+(last-first);
}
}
//실제 copy명령어
template <typename l1, typename l2>
inline l2 copy(l1 first, l1 last, l2 out)
{
//복사하는것의 타입을 알아내서
typedef typename std::iterator_traits<l1>::value_type value_type;
//l1에대해서 "C& C::operator=(const C&);" 와 같은 정의가 없다면
//trivial_assignment operator 를 가지게 됨.
//하지만 컴파일러 능력상 이걸 알아내는건 제각각임;;;
return detail::copy_imp(first, last, out, boost::has_trivial_assign<value_type>());
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
// 이 밑은 위의 소스를 테스트 하는 소스
const int array_size = 1000;
int i_array_[array_size] = {0,};
const int ci_array_[array_size] = {0,};
char c_array_[array_size] = {0,};
const char cc_array_[array_size] = {0,};
int *i_array = i_array_;
const int *ci_array = ci_array_;
char *c_array = c_array_;
const char *cc_array = cc_array_;
const int iter_count = 1000000;
using namespace std;
int cpp_main(int argc, char* argv[])
{
boost::timer t;
double result;
cout << "Measuring times in micro-seconds per "<< array_size << " elements processed" << endl;
cout << "Testing copy... " << endl;
cout << " [some standard liberay version may already perform this optimisation.]" << endl;
//////////////////////////////////////////////////////////////////////////
//cache load
opt::copy(ci_array, ci_array + array_size, i_array);
//time optimised verstion
t.restart();
for(int i=0; i< iter_count; ++i){
opt::copy(ci_array, ci_array + array_size, i_array);
}
result = t.elapsed();
cout << "opt::copy<const int*, int*> : " << result << endl;
//////////////////////////////////////////////////////////////////////////
//cache load;
std::copy(ci_array, ci_array + array_size, i_array);
//time standard version
t.restart();
for(int i=0; i< iter_count; ++i){
std::copy(ci_array, ci_array + array_size, i_array);
}
result = t.elapsed();
cout << "std::copy<const int*, int*> : " << result << endl;
//////////////////////////////////////////////////////////////////////////
//cache load
opt::copy(cc_array, cc_array + array_size, c_array);
//time optimised verstion
t.restart();
for(int i=0; i< iter_count; ++i){
opt::copy(cc_array, cc_array + array_size, c_array);
}
result = t.elapsed();
cout << "opt::copy<const char*, char*> : " << result << endl;
//////////////////////////////////////////////////////////////////////////
//cache load;
std::copy(cc_array, cc_array + array_size, c_array);
//time standard version
t.restart();
for(int i=0; i< iter_count; ++i){
std::copy(cc_array, cc_array + array_size, c_array);
}
result = t.elapsed();
cout << "std::copy<const char*, char*> : " << result << endl;
return 0;
}
메타프로그래밍은 프로그램 소스를 프로그래밍 하는 개념인데...
위의 메모리 복사 예제 처럼 C++의 템플릿을 가지고, 컴파일러가 타입에 따라 가장 적절한 알고리즘을 선택 할 수 있게 하거나
미리 상수 같은걸 프로그램 실행 시점에서 결정하지 않고 컴파일 시점에서 결정하게 하여
더 빠른 프로그램 속도를 갖게 하는 비법? 꼼수? 학문? 인거 같습니다.
진정한 신의 한수... orz....
문제는 내가 아직 이걸 프로젝트에 써먹으면서 머리로 이해 + 손으로 익어야 하는데.......
이 개념 자체가 난해하고 어려워서 자료도 그다지 많이 없고
그나마 boost로 익히는 메타프로그래밍 이라는 책을 사서 봤지만....
미국 책 스타일... orz...
그냥 개념만 쫙 ~~~ 설명됬고... 제가 멍청해서 그런지 개념 잡기가 너무 난해 하네요..
영어로 표현하면 보는 내내 so what? 이라는 느낌밖에 안왔습니다. ㅠㅠ
어쨋든.. 요즘 boost 쪽... 꽤 유용하고 재미있는 프로그래밍 방법론이라 생각하네요..
'C/C++언어' 카테고리의 다른 글
3점의 끼인각을 계산하는 소스 (0) | 2013.12.17 |
---|---|
printf의 흔하진 않지만 때론 굉장히 필요한 포맷들 (0) | 2013.10.23 |
간단한 텍스트 뒤집기, 메모리 복사 함수 (0) | 2012.10.19 |
[ VC11-C++11 ] range base for - 1 (0) | 2012.09.24 |
코드 최적화 팁 (0) | 2012.09.10 |