рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдЦреЛрдЬреЗрдВред CPython рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди

рддрдерд╛рдХрдерд┐рдд рдЖрдИрдЯреА рдЕрдХрд╛рджрдорд┐рдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЗ рд╕реНрдирд╛рддрдХреЛрдВ рдХреА рдкреНрд░рд╕реНрддреБрддрд┐рдпреЛрдВ рдореЗрдВ рдПрдХ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдХрд╛рдлреА рдкрд╣рд▓реЗ, рд╕реНрдкреАрдХрд░ рдХреЛ рдЬрд╛рд╡рд╛ рдореЗрдВ рдЫрдд рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдЦреЛрдЬ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкреВрдЫрд╛ рдЧрдпрд╛ рдерд╛ред рдмреЗрд╢рдХ, рд╕реНрдирд╛рддрдХ рдХреБрдЫ рднреА рд╕рдордЭрджрд╛рд░реА рд╕реЗ рдЬрд╡рд╛рдм рдирд╣реАрдВ рджреЗ рд╕рдХрддрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рд╕рд╡рд╛рд▓ рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓рдВрдмреА рдЯреВрдбреВ-рд╕реВрдЪреА рдореЗрдВ рдбрд╛рд▓ рджрд┐рдпрд╛ред

рдЬреИрд╕реЗ-рдЬреИрд╕реЗ рд╕рдордп рдмреАрддрддрд╛ рдЧрдпрд╛, рдкрд╛рдпрдерди рдореЗрд░реЗ рд▓рд┐рдП рдЙрджреНрдпрдо рдкреНрд▓реЗрдЯрдлрд╛рд░реНрдореЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реЛ рдЧрдпрд╛, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдкрд╛рдпрдерди рдореЗрдВ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдЦреЛрдЬ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рд╣реИред

рд╕реНрдЯреНрд░рд┐рдВрдЧ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдпрд╣рд╛рдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ - рдСрдмреНрдЬреЗрдХреНрдЯ / stringobject.c ред рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдЬреЛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреА рдЦреЛрдЬреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд╝рд┐рдореНрдореЗрджрд╛рд░ рд╣реИ ( рдвреВрдБрдвреЗрдВ , rfind , __contains__ ) рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ / stringlib / find.h рд╣реИред рдпреЗ рд╕рднреА рдлрд╝рдВрдХреНрд╢рдВрд╕ ( рд╕реНрдкреНрд▓рд┐рдЯ , рд░рд┐рдкреНрд▓реЗрд╕ , рдЖрджрд┐ рдХреЗ рд╕рд╛рде) рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ / рд╕реНрдЯреНрд░рд┐рдВрдЧрд▓рд┐рдм / рдлрд╛рд╕реНрдЯрд╕рд░реНрдЪ.рдПрдЪ рдореЗрдВ рд▓рд╛рдЧреВ рд╕рд░реНрдЪ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рд╣рдо рдЙрдирд╕реЗ рдирд┐рдкрдЯреЗрдВрдЧреЗред

рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рд▓реЗрдЦрдХ ( рдлреНрд░реЗрдбреНрд░рд┐рдХ рд▓реБрдВрдб ) рджреНрд╡рд╛рд░рд╛ рдмреЙрдпрд░-рдореВрд░ рдФрд░ рд╣реЙрд░реНрд╕рдкреВрд▓ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХрд╛ рдорд┐рд╢реНрд░рдг рдХрдИ рд╕реБрдзрд╛рд░реЛрдВ рдФрд░ рд╕рд░рд▓реАрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдореЗрдВ рдмреНрд▓реВрдо рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ ред

рдФрд░ рдЗрд╕рд▓рд┐рдП, рдЪрд▓реЛ рдЪрд▓рддреЗ рд╣реИрдВред рд╣реЗрдбрд░
fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n, const STRINGLIB_CHAR* p, Py_ssize_t m, Py_ssize_t maxcount, int mode) /* s - ,   , n -  , p - ,   (  ), m -  , maxcount -    ,       , mode -  /  /    */ 

рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реЛрдиреЗ рд▓рдЧрддрд╛ рд╣реИред рдЖрдЗрдП рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрдердиреЛрдВ рдХреЛ рджреЗрдЦреЗрдВ:
 /*      mode */ #define FAST_COUNT 0 #define FAST_SEARCH 1 #define FAST_RSEARCH 2 /* STRINGLIB_BLOOM_WIDTH    \(   )    32, 64, 128 */ #define STRINGLIB_BLOOM_ADD(mask, ch) ((mask |= (1UL << ((ch) & (STRINGLIB_BLOOM_WIDTH -1))))) #define STRINGLIB_BLOOM(mask, ch) ((mask & (1UL << ((ch) & (STRINGLIB_BLOOM_WIDTH -1))))) 

рдЦрд┐рд▓ рдлрд┐рд▓реНрдЯрд░ рдХреЗ рдЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ? рдЗрд╕рдХреЗ рдЕрдВрддрд┐рдо рд▓реЙрдЧ (STRINGLIB_BLOOM_WIDTH) рдмрд┐рдЯреНрд╕ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдкреНрд░рддреНрдпреЗрдХ рд╡рд░реНрдг рдХреЛ рдПрдХ рд╕рдВрдЦреНрдпрд╛ рджреА рдЧрдИ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ 1 рдХреЗ рд▓рд┐рдП рд╣реИ :
 >>> ord('a') & 31 1 

Q - 17 рдХреЗ рд▓рд┐рдП :
 >>> ord('q') & 31 17 

рддрд╛рд░реНрдХрд┐рдХ "OR" STRINGLIB_BLOOM_ADD рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдлрд╝рд┐рд▓реНрдЯрд░ рдорд╛рд╕реНрдХ рдореЗрдВ рджреЗрдЦреЗ рдЧрдП рд╡рд░реНрдгреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдПрдХрддреНрд░рд┐рдд рд╣реЛрддреА рд╣реИред рдмрд╛рдж рдореЗрдВ, STRINGLIB_BLOOM рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреЛрдИ рд╡рд░реНрдг рдлрд╝рд┐рд▓реНрдЯрд░ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛ рдпрд╛ рдирд╣реАрдВред рдмреЗрд╢рдХ, рдЗрд╕ рдЪреЗрдХ рдореЗрдВ рдЧрд▓рдд рдкреЙрдЬрд╝рд┐рдЯрд┐рд╡ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ ( STRINGLIB_BLOOM рд░рд┐рдЯрд░реНрди 0 рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЪрд░рд┐рддреНрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕реНрдЯреНрд░рд┐рдВрдЧ \ рдлрд╝рд┐рд▓реНрдЯрд░ рдореЗрдВ рдирд╣реАрдВ рд╣реИ):
 >>> ord(']') & 31 29 >>> ord('}') & 31 29 

рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рдлреА рд╕рд╕реНрддрд╛ рд╣реИ рдФрд░ рддреБрд▓рдирд╛ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред

рдЕрдм рд╣рдо рдПрд▓реНрдЧреЛрд░рд┐рдердо рдкрд░ рдЖрдЧреЗ рдмрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рд╕реНрдкрд╖реНрдЯ рддрд░реНрдХ m> n рдФрд░ m <= 1 :
  w = n - m; if (w < 0 || (mode == FAST_COUNT && maxcount == 0)) return -1; 

рдФрд░ рдХреЛрдб рдХрд╛ рдПрдХ рд╣рд┐рд╕реНрд╕рд╛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рд▓реЗрдЦ рдХреЛ рдлрд╛рдбрд╝рд╛ рди рдЬрд╛рдП):
  if (m <= 1) { if (m <= 0) return -1; if (mode == FAST_COUNT) { /* ... */ } else if (mode == FAST_SEARCH) { for (i = 0; i < n; i++) if (s[i] == p[0]) return i; } else { /* FAST_RSEARCH */ /* ... */ } return -1; } 

рдЙрд╕рдХреЗ рдмрд╛рдж, рдХрдИ рдирдП рдЪрд░ рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВ рдФрд░ рдЖрд╡рд╢реНрдпрдХ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд▓рд┐рдП рдорд╛рд╕реНрдХ рднрд░рд╛ рдЬрд╛рддрд╛ рд╣реИ:
  mlast = m - 1; skip = mlast - 1; mask = 0; for (i = 0; i < mlast; i++) { STRINGLIB_BLOOM_ADD(mask, p[i]); if (p[i] == p[mlast]) skip = mlast - i - 1; } STRINGLIB_BLOOM_ADD(mask, p[mlast]); 

рдЫреЛрдбрд╝реЗрдВ - рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрдЦреНрдпрд╛, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдпрд╣ рдЦреЛрдЬ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдорд╛рдЗрдирд╕ рдХреЗ рдЕрдВрддрд┐рдо рд╡рд░реНрдг рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИред рдпрджрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдкрд┐рдЫрд▓реЗ рдХреЗ рдмрд░рд╛рдмрд░ рд╡рд░реНрдг рд╣реИрдВ, рддреЛ рдЫреЛрдбрд╝реЗрдВ , рдЕрдВрддрд┐рдо рд╡рд░реНрдг рдФрд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рдЕрдВрддрд┐рдо рд╡рд░реНрдг рдХреЗ рд╕реВрдЪрдХ рдХреЗ рдмреАрдЪ рдХрд╛ рдЕрдВрддрд░ рд╣реИред

рд╡рд┐рдХрд┐рдкреАрдбрд┐рдпрд╛ рд╕реЗ рдореБрдЦреНрдп рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╡рд┐рдЪрд╛рд░ рдХрд╛ рд╡рд┐рд╡рд░рдг:

рдмрд╛рдПрдВ рд╕реЗ рджрд╛рдПрдВ рд╕реНрдХреИрди рдХрд░реЗрдВ, рджрд╛рдПрдВ рд╕реЗ рдмрд╛рдПрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░реЗрдВред рдкрд╛рда рдХреА рд╢реБрд░реБрдЖрдд (рд░реЗрдЦрд╛) рдФрд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕рдВрдпреБрдХреНрдд рд╣реИ, рдЪреЗрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдЕрдВрддрд┐рдо рдЪрд░рд┐рддреНрд░ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред рдпрджрд┐ рд╡рд░реНрдгреЛрдВ рдХрд╛ рдорд┐рд▓рд╛рди рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдкреИрдЯрд░реНрди рдХреЗ рдкрд╛рд░рдорд╛рд░реНрдерд┐рдХ рдЪрд░рд┐рддреНрд░ рдХреА рддреБрд▓рдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ, рдЖрджрд┐ред рдпрджрд┐ рдкреИрдЯрд░реНрди рдХреЗ рд╕рднреА рдЕрдХреНрд╖рд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд╕реБрдкрд░рд┐рдВрдкрд▓ рд╡рд░реНрдгреЛрдВ рд╕реЗ рдореЗрд▓ рдЦрд╛рддреЗ рд╣реИрдВ, рддреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЦреЛрдЬ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рддреА рд╣реИред

рдпрджрд┐ рдкреИрдЯрд░реНрди рдХрд╛ рдХреБрдЫ рд╡рд░реНрдг рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд╕рдВрдЧрдд рд╡рд░реНрдг рдХреЗ рд╕рд╛рде рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддрд╛ рд╣реИ, рддреЛ рдкреИрдЯрд░реНрди рдХреЛ рдХрдИ рд╡рд░реНрдгреЛрдВ рдХреЛ рджрд╛рдИрдВ рдУрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЕрдВрддрд┐рдо рд╡рд░реНрдг рдХреЗ рд╕рд╛рде рдЪреЗрдХ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕ рд╡рд┐рд╡рд░рдг рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди (рдКрдкрд░ w = n - m ):
  for (i = 0; i <= w; i++) { if (s[i+m-1] == p[m-1]) { /* ,      */ for (j = 0; j < mlast; j++) if (s[i+j] != p[j]) break; if (j == mlast) { /*  ! */ if (mode != FAST_COUNT) /*       - ,     */ return i; /*     */ count++; if (count == maxcount) return maxcount; i = i + mlast; continue; } /*         ,      */ /*      ,        */ if (!STRINGLIB_BLOOM(mask, s[i+m])) /*  ,           */ i = i + m; else /*  ,        'skip' */ i = i + skip; } else { /*     .      ,        */ if (!STRINGLIB_BLOOM(mask, s[i+m])) /*  ,           */ i = i + m; /*   , i++ */ } } 

рдереЛрдбрд╝рд╛ рд╕рд╛ рджреГрд╢реНрдпред рдЖрдЗрдП рд╣рдо рд╕реНрдЯреНрд░рд┐рдВрдЧ "рдбреНрд░рдо" рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ рдФрд░ рд╡рд┐рдХрд▓реНрдк "рдЕрдмрд╛" рдХреА рддрд▓рд╛рд╢ рдХрд░реЗрдВ:
     skip = 1 i = 0: ______________ |||||||| | -  , i++ _______ |||| i = 1: ______________ |||||||| | -  ,   _______ |||| ______________ |||||||| | -  .    ""  ""   ,   skip,   for   i += 2 _______ |||| i = 3: ______________ |||||||| | -  ,   _______ |||| ______________ |||||||| | -  ,   _______ |||| ______________ |||||||| | -  ,   _______ |||| 

рдЦреИрд░, рдпрд╣ рдмрд╛рдд рд╣реИред

рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рдкрд╕рдВрдж рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЕрднреА рднреА рдкрд╛рдпрдерди рд╕реНрд░реЛрдд рдореЗрдВ рд╕реНрдерд╛рдиреЛрдВ рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рд╣реИ рдЬреЛ рдЦреБрджрд╛рдИ рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ / listobject.c рдпрд╛ dict.get рдХрд╛ рд▓рд┐рд╕реНрдЯ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рдирд╛ ред

рд╢реБрднрдХрд╛рдордирд╛рдПрдБ! :)

Source: https://habr.com/ru/post/In132156/


All Articles