commit 2025-09-19 22:55 Optimize Replace() in ZtCStringBase

This commit is contained in:
2025-09-19 22:55:40 +09:00
parent 0ca2981290
commit 500c806dbd
3 changed files with 167 additions and 121 deletions

View File

@ -91,13 +91,12 @@ namespace ZNsMain
##########################################################*/ ##########################################################*/
template<typename TPosList> ZCStringStd& ReplaceToOutByPosList template<typename TPosList> ZCStringStd& ReplaceByPosList
( (
TPosList& AR_CPosList , TPosList& AR_CPosList ,
TypeCPChar APC_Replace , TypeCPChar APC_Replace ,
TypeLength AL_Replace , TypeLength AL_Replace ,
TypeLength AL_Searched , TypeLength AL_Searched
ZCStringStd& ARR_SaveOut
) )
/*##########################################################*/ /*##########################################################*/
{ {
@ -118,6 +117,12 @@ namespace ZNsMain
TypeLength VL_SearchedPos= 0 ; TypeLength VL_SearchedPos= 0 ;
TypeLength VL_SearchedPre= 0 ; // VL_SearchedPos 의 이전 값 TypeLength VL_SearchedPre= 0 ; // VL_SearchedPos 의 이전 값
TypePChar VPC_MoveStart = 0 ;
TypePChar VPC_DestStart = 0 ;
TypeLength VL_MoveStart = 0 ;
TypeLength VL_DestStart = 0 ;
TypeLength VL_MemMoveSize= 0 ;
if(AL_Replace<=AL_Searched) // 메모리 증가 불필요 if(AL_Replace<=AL_Searched) // 메모리 증가 불필요
{ {
TypePChar VPC_MoveStart = 0 ; TypePChar VPC_MoveStart = 0 ;
@ -177,75 +182,54 @@ namespace ZNsMain
if(AL_Replace<=AL_Searched) // 메모리 증가 불필요*/ if(AL_Replace<=AL_Searched) // 메모리 증가 불필요*/
ARR_SaveOut.resize(VL_NeedSize); /*======*/ VL_SearchedPre = this->size() ;
/*======*/ VH_IterEasyID = AR_CPosList.ItTID() ;
TypeLength VL_NowEleNo = VL_PosListSize ;
TypeLength VL_DiffLength = AL_Replace-AL_Searched;
TypePChar VPC_OutStart = const_cast<char*>(ARR_SaveOut.data()) ; this->resize(VL_NeedSize); VPC_ThisStart = this->data();
TypePChar VPC_CopyStart = 0 ;
TypePChar VPC_DestStart = 0 ;
TypeLength VL_CopyStart = 0 ;
TypeLength VL_DestStart = 0 ;
TypeLength VL_MemCopySize= 0 ;
TypePChar VPC_RepalcePos= 0 ;
__for1(TypeLength, i, VL_PosListSize) __for1(TypeLength, i, VL_PosListSize)
{ {
VL_SearchedPos = AR_CPosList.ItD(VH_IterEasyID) ; VL_SearchedPos = AR_CPosList.ItD(VH_IterEasyID) ;
VPC_CopyStart = VPC_ThisStart + VL_SearchedPre ; VL_MemMoveSize = VL_SearchedPre - (VL_SearchedPos+AL_Searched);
VL_DestStart = VL_SearchedPre +
( AL_Replace-AL_Searched ) * (i-1) ;
VPC_DestStart = VPC_OutStart + VL_DestStart ;
if(VL_SearchedPos>VL_SearchedPre) if(VL_MemMoveSize>0)
{ {
VL_MemCopySize = VPC_MoveStart = VPC_ThisStart + VL_SearchedPos + AL_Searched ;
VL_SearchedPos - VL_SearchedPre ; VPC_DestStart = VPC_ThisStart + VL_SearchedPos + AL_Searched + VL_DiffLength*VL_NowEleNo ;
::memcpy /*:::::::::::::::::::::::::::::::::::::::*/ ::memmove /*::::::::::::::::::::::::::::::::::::::::*/
( (
VPC_DestStart, VPC_CopyStart, VL_MemCopySize VPC_DestStart, VPC_MoveStart, VL_MemMoveSize
); );
/*::::::::::::::::::::::::::::::::::::::::::::::::*/ /*::::::::::::::::::::::::::::::::::::::::::::::::::*/
}/* }/*
if(VL_SearchedPos>VL_SearchedPre)*/ if(VL_MemMoveSize>0)*/
VL_SearchedPre = VL_SearchedPos + AL_Searched ; VPC_DestStart = VPC_ThisStart + VL_SearchedPos + VL_DiffLength*(VL_PosListSize - i) ;
VL_DestStart = VL_SearchedPos +
( AL_Replace-AL_Searched ) * (i-1) ;
VPC_RepalcePos = VPC_OutStart + VL_DestStart ;
::memcpy(VPC_RepalcePos, APC_Replace, AL_Replace) ; ::memcpy /*::::::::::::::::::::::::::::::::::::::::*/
(
VPC_DestStart, APC_Replace, AL_Replace
);
/*::::::::::::::::::::::::::::::::::::::::::::::::::*/
AR_CPosList.ItNext(VH_IterEasyID); VL_SearchedPre = VL_SearchedPos; --VL_NowEleNo;
AR_CPosList.ItPrev(VH_IterEasyID);
}/* }/*
__for1(TypeLength, i, VL_PosListSize)*/ __for1(TypeLength, i, VL_PosListSize)*/
if(VL_SearchedPre<VL_ThisSize) return *this;
{
VL_DestStart = VL_DestStart + AL_Replace ;
VPC_DestStart = VPC_OutStart + VL_DestStart ;
VPC_CopyStart = VPC_ThisStart+ VL_SearchedPre;
VL_MemCopySize = VL_ThisSize - VL_SearchedPre;
::memcpy /*:::::::::::::::::::::::::::::::::::::::*/
(
VPC_DestStart, VPC_CopyStart, VL_MemCopySize
);
/*::::::::::::::::::::::::::::::::::::::::::::::::*/
}/* }/*
if(VL_SearchedPre<VL_ThisSize)*/ template<typename TPosList> ZCStringStd& ReplaceByPosList
return ARR_SaveOut;
}/*
template<typename TPosList> ZCStringStd& ReplaceToOutByPosList
( (
TPosList& AR_CPosList , TPosList& AR_CPosList ,
TypeCPChar APC_Replace , TypeCPChar APC_Replace ,
TypeLength AL_Replace , TypeLength AL_Replace ,
TypeLength AL_Searched , TypeLength AL_Searched
ZCStringStd& ARR_SaveOut
) )
############################################################*/ ############################################################*/
@ -267,12 +251,11 @@ namespace ZNsMain
); );
/*////////////////////////////////////////////*/ /*////////////////////////////////////////////*/
ZCStringStd VO_CStringOut; return *this = ReplaceToOutByPosList return ReplaceByPosList /*::::::::::::::::::::::::::::*/
( (
VO_CPosCList, APC_Replace, AL_Replace, AL_Search, RR(VO_CStringOut) VO_CPosCList, APC_Replace, AL_Replace, AL_Search
); );
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ /*::::::::::::::::::::::::::::::::::::::::::::::::::::*/
}/* }/*
ZCStringStd& Replace /*###################################################### ZCStringStd& Replace /*######################################################
( (

View File

@ -1066,7 +1066,7 @@ namespace ZNsMain
else if(AP_CutLink==mp_TailLink) else if(AP_CutLink==mp_TailLink)
{ {
#if(_CODE_NEW_) #if(_CODE_NEW_)
mp_Tailink= AP_PrevLink; mp_TailLink= AP_PrevLink;
#else #else
AP_PrevLink->mp_NextLink= 0; AP_PrevLink->mp_NextLink= 0;
#endif #endif
@ -1108,7 +1108,7 @@ namespace ZNsMain
else if(AP_CutLink==mp_TailLink) else if(AP_CutLink==mp_TailLink)
{ {
#if(_CODE_NEW_) #if(_CODE_NEW_)
mp_Tailink= AP_PrevLink; mp_TailLink= AP_PrevLink;
#else #else
AP_PrevLink->mp_NextLink=0; AP_PrevLink->mp_NextLink=0;
#endif #endif

View File

@ -357,20 +357,109 @@ namespace ZNsMain
##########################################################*/ ##########################################################*/
template<typename TPosList> ZCStringBase& ReplaceToOutByPosList /*//////////////////////////////////////////////////////////
■ -- 2025-09-19 20:11
■ AL_Searched >= AL_Replace
□ 메모리 증가 불필요.
□ 찾은 원소의 시작 원소부터 memmove() 호출.
■ AL_Searched < AL_Replace
□ 메모리 증가 필요.
□ 찾은 원소의 끝쪽 원소부터 memmove() 호출
# 원본 : 12###345###6789###AB
# 교체본 : 12#####345#####6789#####AB
# 교체 문자열 : #####
# 찾은 문자 길이 : 3(###)
# 교체 문자 길이 : 5(#####)
# 문자 길이 차이 : 2(#####-###)
# 처리 순서-01
AB 를 맨 뒤로 이동.
memmove() 시작 위치 : 원본의 3번 ### 위치 + 찾은 문자 길이
memmove() 대상 위치 : 원본의 3번 ### 위치 + 찾은 문자 길이 + 문자 길이 차이 * 3
memmove() 처리 길이 : 원본의 전체 길이 - (원본의 3번 ### 위치 + 찾은 문자 길이)
# 처리 순서-02
원본의 3번 ### 에 memmcpy()
memcpy() 시작 위치 : 교체 문자열
memcpy() 대상 위치 : 원본의 3번 ### 위치 + 문자 길이 차이 * (3 - 1)
memcpy() 처리 길이 : 교체 문자 길이
# 처리 순서-11
6789 를 뒤로 이동.
memmove() 시작 위치 : 원본의 2번 ### 위치 + 찾은 문자 길이
memmove() 대상 위치 : 원본의 2번 ### 위치 + 찾은 문자 길이 + 문자 길이 차이 * 2
memmove() 처리 길이 : 원본의 3번 ### 위치 - (원본의 2번 ### 위치 + 찾은 문자 길이)
# 처리 순서-12
원본의 2번 ### 에 memmcpy()
memcpy() 시작 위치 : 교체 문자열
memcpy() 대상 위치 : 원본의 2번 ### 위치 + 문자 길이 차이 * (3 - 2)
memcpy() 처리 길이 : 교체 문자 길이
......
□ 위를 이렇게 다시 정리한다.
TypeLength VL_PosListSize = AR_CPosList.size();
TypeLength VL_SearchedPre = this->size() ; // 현재 순회 중인 원소의 다음의 원소가 가리키는, 원본에서의 시작 위치.
TypeLength VL_NowEleNo = VL_PosListSize ; // AR_CPosList 에서 순회 중인 원소의 순서. 처음이 1.
TypeLength VL_DiffLength = AL_Replace-AL_Searched ;
TypeLength VL_SearchedPos : VL_NowEleNo 번 원소가 가리키는, 원본에서의 시작 위치
TypeLength AL_Searched : 인수, 찾은 문자 길이
TypeLength AL_Replace : 인수, 교체 문자 길이
TypeLength APC_Replace : 인수, 교체 문자열
TypeLength i : 순회 증가 번호. 1부터 시작.
# 처리 순서-101
AB 를 맨 뒤로 이동.
memmove() 시작 위치 : VL_SearchedPos + AL_Searched
memmove() 대상 위치 : VL_SearchedPos + AL_Searched + VL_DiffLength * VL_NowEleNo
memmove() 처리 길이 : VL_SearchedPre - (VL_SearchedPos + AL_Searched)
# 처리 순서-102
원본의 3번 ### 에 memcpy()
memcpy() 시작 위치 : APC_Replace
memcpy() 대상 위치 : VL_SearchedPos + VL_DiffLength * (VL_PosListSize - i)
memcpy() 처리 길이 : AL_Replace
--VL_NowEleNo ;
VL_SearchedPre = VL_SearchedPos ;
VL_SearchedPos 을 다음 순회 원소를 참고해 설정.
/////////////////////////////////////////////////////////////////////////*/
template<typename TPosList> ZCStringBase& ReplaceByPosList ////////////////
( (
TPosList& AR_CPosList , TPosList& AR_CPosList ,
TypeCPChar APC_Replace , TypeCPChar APC_Replace ,
TypeLength AL_Replace , TypeLength AL_Replace ,
TypeLength AL_Searched , TypeLength AL_Searched
ZCStringBase& ARR_SaveOut
) )
/*###########################################################*/ /*#######################################################################*/
{ {
// TPosList : ZNsMain::ZtCList<TypeLength> etc // TPosList : ZNsMain::ZtCList<TypeLength> etc
// AL_Replace : APC_Replace 의 길이 // AL_Replace : APC_Replace 의 길이
// AL_Searched : 이전에 찾은 길이 // AL_Searched : 이전에 찾은 길이
// ARR_SaveOut : AL_Replace>AL_Searched 인 경우에 여기에 저장한다.
if(AR_CPosList.size()<1) return *this; if(AR_CPosList.size()<1) return *this;
@ -384,14 +473,14 @@ namespace ZNsMain
TypeLength VL_SearchedPos= 0 ; TypeLength VL_SearchedPos= 0 ;
TypeLength VL_SearchedPre= 0 ; // VL_SearchedPos 의 이전 값 TypeLength VL_SearchedPre= 0 ; // VL_SearchedPos 의 이전 값
if(AL_Replace<=AL_Searched) // 메모리 증가 불필요
{
TypePChar VPC_MoveStart = 0 ; TypePChar VPC_MoveStart = 0 ;
TypePChar VPC_DestStart = 0 ; TypePChar VPC_DestStart = 0 ;
TypeLength VL_MoveStart = 0 ; TypeLength VL_MoveStart = 0 ;
TypeLength VL_DestStart = 0 ; TypeLength VL_DestStart = 0 ;
TypeLength VL_MemMoveSize= 0 ; TypeLength VL_MemMoveSize= 0 ;
if(AL_Replace<=AL_Searched) // 메모리 증가 불필요
{
TypePChar VPC_RepalcePos= 0 ; TypePChar VPC_RepalcePos= 0 ;
__for1(TypeLength, i, VL_PosListSize) __for1(TypeLength, i, VL_PosListSize)
@ -447,81 +536,56 @@ namespace ZNsMain
if(AL_Replace<=AL_Searched) // 메모리 증가 불필요*/ if(AL_Replace<=AL_Searched) // 메모리 증가 불필요*/
ARR_SaveOut.resize(VL_NeedSize); /*======*/ VL_SearchedPre = this->size() ;
/*======*/ VH_IterEasyID = AR_CPosList.ItTID() ;
TypeLength VL_NowEleNo = VL_PosListSize ;
TypeLength VL_DiffLength = AL_Replace-AL_Searched;
TypePChar VPC_OutStart = ARR_SaveOut.data() ; this->resize(VL_NeedSize); VPC_ThisStart = this->data();
TypePChar VPC_CopyStart = 0 ;
TypePChar VPC_DestStart = 0 ;
TypeLength VL_CopyStart = 0 ;
TypeLength VL_DestStart = 0 ;
TypeLength VL_MemCopySize= 0 ;
TypePChar VPC_RepalcePos= 0 ;
__for1(TypeLength, i, VL_PosListSize) __for1(TypeLength, i, VL_PosListSize)
{ {
VL_SearchedPos = AR_CPosList.ItD(VH_IterEasyID) ; VL_SearchedPos = AR_CPosList.ItD(VH_IterEasyID) ;
VPC_CopyStart = VPC_ThisStart + VL_SearchedPre ; VL_MemMoveSize = VL_SearchedPre - (VL_SearchedPos+AL_Searched);
VL_DestStart = VL_SearchedPre +
( AL_Replace-AL_Searched ) * (i-1) ;
VPC_DestStart = VPC_OutStart + VL_DestStart ;
if(VL_SearchedPos>VL_SearchedPre) if(VL_MemMoveSize>0)
{ {
VL_MemCopySize = VPC_MoveStart = VPC_ThisStart + VL_SearchedPos + AL_Searched ;
VL_SearchedPos - VL_SearchedPre ; VPC_DestStart = VPC_ThisStart + VL_SearchedPos + AL_Searched + VL_DiffLength*VL_NowEleNo ;
::memcpy /*::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ ::memmove /*::::::::::::::::::::::::::::::::::::::::*/
( (
VPC_DestStart, VPC_CopyStart, VL_MemCopySize*sizeof(TypeChar) VPC_DestStart, VPC_MoveStart, VL_MemMoveSize
); );
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ /*::::::::::::::::::::::::::::::::::::::::::::::::::*/
}/* }/*
if(VL_SearchedPos>VL_SearchedPre)*/ if(VL_MemMoveSize>0)*/
VL_SearchedPre = VL_SearchedPos + AL_Searched ; VPC_DestStart = VPC_ThisStart + VL_SearchedPos + VL_DiffLength*(VL_PosListSize - i) ;
VL_DestStart = VL_SearchedPos +
( AL_Replace-AL_Searched ) * (i-1) ;
VPC_RepalcePos = VPC_OutStart + VL_DestStart ;
::memcpy /*:::::::::::::::::::::::::::::::::::::::::::::::::::*/ ::memcpy /*::::::::::::::::::::::::::::::::::::::::*/
( (
VPC_RepalcePos, APC_Replace, AL_Replace*sizeof(TypeChar) VPC_DestStart, APC_Replace, AL_Replace
) ; );
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ /*::::::::::::::::::::::::::::::::::::::::::::::::::*/
AR_CPosList.ItNext(VH_IterEasyID); VL_SearchedPre = VL_SearchedPos; --VL_NowEleNo;
AR_CPosList.ItPrev(VH_IterEasyID);
}/* }/*
__for1(TypeLength, i, VL_PosListSize)*/ __for1(TypeLength, i, VL_PosListSize)*/
if(VL_SearchedPre<VL_ThisSize) return *this;
{
VL_DestStart = VL_DestStart + AL_Replace ;
VPC_DestStart = VPC_OutStart + VL_DestStart ;
VPC_CopyStart = VPC_ThisStart+ VL_SearchedPre;
VL_MemCopySize = VL_ThisSize - VL_SearchedPre;
::memcpy /*::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
(
VPC_DestStart, VPC_CopyStart, VL_MemCopySize*sizeof(TypeChar)
);
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
}/* }/*
if(VL_SearchedPre<VL_ThisSize)*/ template<typename TPosList> ZCStringBase& ReplaceByPosList ////////////////
return ARR_SaveOut;
}/*
template<typename TPosList> ZCStringBase& ReplaceToOutByPosList
( (
TPosList& AR_CPosList , TPosList& AR_CPosList ,
TypeCPChar APC_Replace , TypeCPChar APC_Replace ,
TypeLength AL_Replace , TypeLength AL_Replace ,
TypeLength AL_Searched , TypeLength AL_Searched
ZCStringBase& ARR_SaveOut
) )
#############################################################*/ #########################################################################*/
/* template<typename TSearchInfoList> void MakeSplitInfoList() /* template<typename TSearchInfoList> void MakeSplitInfoList()
@ -1775,12 +1839,11 @@ namespace ZNsMain
); );
/*////////////////////////////////////////////*/ /*////////////////////////////////////////////*/
ZCStringBase VO_CStringOut; return *this = ReplaceToOutByPosList return ReplaceByPosList /*::::::::::::::::::::::::::::*/
( (
VO_CPosCList, APC_Replace, AL_Replace, AL_Search, RR(VO_CStringOut) VO_CPosCList, APC_Replace, AL_Replace, AL_Search
); );
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ /*::::::::::::::::::::::::::::::::::::::::::::::::::::*/
}/* }/*
ZCStringBase& Replace /*###################################################### ZCStringBase& Replace /*######################################################
( (