പ്രതിഫലനം ത്വരിതപ്പെടുത്തുന്നതിനെക്കുറിച്ചുള്ള ലേഖനം പരാജയപ്പെട്ടു

ലേഖനത്തിന്റെ തലക്കെട്ട് ഞാൻ ഉടൻ വിശദീകരിക്കും. ലളിതവും എന്നാൽ യാഥാർത്ഥ്യവുമായ ഒരു ഉദാഹരണം ഉപയോഗിച്ച് പ്രതിഫലനത്തിന്റെ ഉപയോഗം എങ്ങനെ വേഗത്തിലാക്കാം എന്നതിനെക്കുറിച്ചുള്ള നല്ലതും വിശ്വസനീയവുമായ ഉപദേശം നൽകുക എന്നതായിരുന്നു യഥാർത്ഥ പദ്ധതി, എന്നാൽ ബെഞ്ച്മാർക്കിംഗിൽ പ്രതിഫലനം ഞാൻ വിചാരിച്ചതുപോലെ മന്ദഗതിയിലല്ലെന്ന് മനസ്സിലായി, എന്റെ പേടിസ്വപ്നങ്ങളേക്കാൾ LINQ വേഗത കുറവാണ്. പക്ഷേ, അവസാനം എനിക്കും അളവുകളിൽ പിഴവ് സംഭവിച്ചു എന്ന് മനസ്സിലായി... ഈ ജീവിതകഥയുടെ വിശദാംശങ്ങൾ കട്ടിലും കമന്റിലും ഉണ്ട്. ഒരു എന്റർപ്രൈസസിൽ സാധാരണയായി ചെയ്യുന്നതുപോലെ ഈ ഉദാഹരണം വളരെ സാധാരണവും തത്വത്തിൽ നടപ്പിലാക്കിയതുമായതിനാൽ, ഇത് വളരെ രസകരമായി മാറി, എനിക്ക് തോന്നുന്നത് പോലെ, ജീവിതത്തിന്റെ പ്രകടനമാണ്: ലേഖനത്തിന്റെ പ്രധാന വിഷയത്തിന്റെ വേഗതയെ സ്വാധീനിച്ചത് ബാഹ്യ ലോജിക് കാരണം ശ്രദ്ധിക്കപ്പെടുന്നില്ല: Moq, Autofac, EF കോർ എന്നിവയും മറ്റുള്ളവ "ബാൻഡിംഗുകളും".

ഈ ലേഖനത്തിന്റെ ധാരണയിൽ ഞാൻ പ്രവർത്തിക്കാൻ തുടങ്ങി: എന്തുകൊണ്ടാണ് പ്രതിഫലനം മന്ദഗതിയിലാകുന്നത്

നിങ്ങൾക്ക് കാണാനാകുന്നതുപോലെ, ആപ്ലിക്കേഷനെ വളരെയധികം വേഗത്തിലാക്കാനുള്ള മികച്ച മാർഗമായി പ്രതിഫലന തരം രീതികളെ നേരിട്ട് വിളിക്കുന്നതിന് പകരം സമാഹരിച്ച ഡെലിഗേറ്റുകൾ ഉപയോഗിക്കാൻ രചയിതാവ് നിർദ്ദേശിക്കുന്നു. തീർച്ചയായും, ഐഎൽ എമിഷൻ ഉണ്ട്, പക്ഷേ ഇത് ഒഴിവാക്കാൻ ഞാൻ ആഗ്രഹിക്കുന്നു, കാരണം ഇത് ജോലി നിർവഹിക്കാനുള്ള ഏറ്റവും അധ്വാനമുള്ള മാർഗമാണ്, ഇത് പിശകുകൾ നിറഞ്ഞതാണ്.

പ്രതിഫലനത്തിന്റെ വേഗതയെക്കുറിച്ച് എനിക്ക് എല്ലായ്പ്പോഴും സമാനമായ അഭിപ്രായം ഉണ്ടെന്ന് കണക്കിലെടുക്കുമ്പോൾ, രചയിതാവിന്റെ നിഗമനങ്ങളെ ചോദ്യം ചെയ്യാൻ ഞാൻ പ്രത്യേകിച്ച് ഉദ്ദേശിച്ചിട്ടില്ല.

എന്റർപ്രൈസസിൽ പ്രതിഫലനത്തിന്റെ നിഷ്കളങ്കമായ ഉപയോഗം ഞാൻ പലപ്പോഴും നേരിടുന്നു. തരം എടുത്തിട്ടുണ്ട്. വസ്തുവകകളുടെ വിവരങ്ങൾ ശേഖരിച്ചു. SetValue രീതി വിളിക്കുന്നു, എല്ലാവരും സന്തോഷിക്കുന്നു. ടാർഗെറ്റ് ഫീൽഡിൽ മൂല്യം എത്തി, എല്ലാവരും സന്തോഷത്തിലാണ്. വളരെ മിടുക്കരായ ആളുകൾ - സീനിയർമാരും ടീം ലീഡുകളും - അവരുടെ വിപുലീകരണങ്ങൾ ഒബ്‌ജക്‌റ്റിലേക്ക് എഴുതുന്നു, അത്തരം നിഷ്‌കളങ്കമായ നടപ്പാക്കലിനെ അടിസ്ഥാനമാക്കി "സാർവത്രിക" മാപ്പർമാർ ഒരു തരത്തിലേക്ക് മറ്റൊന്നിലേക്ക്. സാരാംശം സാധാരണയായി ഇതാണ്: ഞങ്ങൾ എല്ലാ ഫീൽഡുകളും എടുക്കുന്നു, എല്ലാ പ്രോപ്പർട്ടികളും എടുക്കുന്നു, അവയ്ക്ക് മുകളിൽ ആവർത്തിക്കുന്നു: തരം അംഗങ്ങളുടെ പേരുകൾ പൊരുത്തപ്പെടുന്നുവെങ്കിൽ, ഞങ്ങൾ SetValue എക്സിക്യൂട്ട് ചെയ്യുന്നു. ഒരു തരത്തിൽ ചില പ്രോപ്പർട്ടി കണ്ടെത്താത്ത പിശകുകൾ കാരണം കാലാകാലങ്ങളിൽ ഞങ്ങൾ ഒഴിവാക്കലുകൾ പിടിക്കുന്നു, എന്നാൽ ഇവിടെ പോലും പ്രകടനം മെച്ചപ്പെടുത്തുന്ന ഒരു വഴിയുണ്ട്. ശ്രമിക്കുക/പിടിക്കുക.

ആളുകൾക്ക് മുമ്പ് വന്ന യന്ത്രങ്ങൾ എങ്ങനെ പ്രവർത്തിക്കുന്നു എന്നതിനെക്കുറിച്ചുള്ള വിവരങ്ങൾ പൂർണ്ണമായും സജ്ജീകരിക്കാതെ പാഴ്‌സറുകളും മാപ്പറുകളും പുനർനിർമ്മിക്കുന്നത് ഞാൻ കണ്ടിട്ടുണ്ട്. ആളുകൾ അവരുടെ നിഷ്കളങ്കമായ നടപ്പാക്കലുകൾ തന്ത്രങ്ങൾക്ക് പിന്നിൽ, ഇന്റർഫേസുകൾക്ക് പിന്നിൽ, കുത്തിവയ്പ്പുകൾക്ക് പിന്നിൽ മറയ്ക്കുന്നത് ഞാൻ കണ്ടിട്ടുണ്ട്, ഇത് തുടർന്നുള്ള ബച്ചനാലിയയെ ക്ഷമിക്കും. അത്തരം തിരിച്ചറിവുകളിൽ ഞാൻ മൂക്ക് ഉയർത്തി. വാസ്തവത്തിൽ, ഞാൻ യഥാർത്ഥ പ്രകടന ചോർച്ച അളന്നില്ല, സാധ്യമെങ്കിൽ, എന്റെ കൈയിൽ കിട്ടുമെങ്കിൽ ഞാൻ നടപ്പിലാക്കൽ കൂടുതൽ "ഒപ്റ്റിമൽ" ആയി മാറ്റി. അതിനാൽ, ചുവടെ ചർച്ച ചെയ്ത ആദ്യ അളവുകൾ എന്നെ ഗുരുതരമായി ആശയക്കുഴപ്പത്തിലാക്കി.

നിങ്ങളിൽ പലരും, റിക്ടർ അല്ലെങ്കിൽ മറ്റ് പ്രത്യയശാസ്ത്രജ്ഞർ വായിക്കുമ്പോൾ, കോഡിലെ പ്രതിഫലനം ആപ്ലിക്കേഷന്റെ പ്രകടനത്തെ അങ്ങേയറ്റം പ്രതികൂലമായി ബാധിക്കുന്ന ഒരു പ്രതിഭാസമാണെന്ന തികച്ചും ന്യായമായ ഒരു പ്രസ്താവന കണ്ടതായി ഞാൻ കരുതുന്നു.

കോളിംഗ് റിഫ്‌ളക്ഷൻ CLR-നെ അസംബ്ലികളിലൂടെ അവർക്ക് ആവശ്യമുള്ളത് കണ്ടെത്താനും മെറ്റാഡാറ്റ ഉയർത്താനും പാഴ്‌സ് ചെയ്യാനും പ്രേരിപ്പിക്കുന്നു. കൂടാതെ, ക്രമങ്ങളിലൂടെ കടന്നുപോകുമ്പോൾ പ്രതിഫലിക്കുന്നത് വലിയ അളവിലുള്ള മെമ്മറിയുടെ അലോക്കേഷനിലേക്ക് നയിക്കുന്നു. ഞങ്ങൾ മെമ്മറി ഉപയോഗിക്കുന്നു, CLR GC അനാവരണം ചെയ്യുകയും ഫ്രൈസുകൾ ആരംഭിക്കുകയും ചെയ്യുന്നു. ഇത് വളരെ മന്ദഗതിയിലായിരിക്കണം, എന്നെ വിശ്വസിക്കൂ. ആധുനിക പ്രൊഡക്ഷൻ സെർവറുകളിലോ ക്ലൗഡ് മെഷീനുകളിലോ ഉള്ള വലിയ അളവിലുള്ള മെമ്മറി ഉയർന്ന പ്രോസസ്സിംഗ് കാലതാമസം തടയുന്നില്ല. വാസ്തവത്തിൽ, കൂടുതൽ മെമ്മറി, GC എങ്ങനെ പ്രവർത്തിക്കുന്നു എന്ന് നിങ്ങൾ ശ്രദ്ധിക്കും. സിദ്ധാന്തത്തിൽ, പ്രതിഫലനം അദ്ദേഹത്തിന് ഒരു അധിക ചുവന്ന തുണിക്കഷണമാണ്.

എന്നിരുന്നാലും, ഞങ്ങൾ എല്ലാവരും IoC കണ്ടെയ്‌നറുകളും തീയതി മാപ്പറുകളും ഉപയോഗിക്കുന്നു, ഇതിന്റെ പ്രവർത്തന തത്വവും പ്രതിഫലനത്തെ അടിസ്ഥാനമാക്കിയുള്ളതാണ്, എന്നാൽ അവയുടെ പ്രകടനത്തെക്കുറിച്ച് സാധാരണയായി ചോദ്യങ്ങളൊന്നുമില്ല. അല്ല, ഡിപൻഡൻസികളുടെ ആമുഖവും ബാഹ്യ പരിമിത സന്ദർഭ മോഡലുകളിൽ നിന്നുള്ള അമൂർത്തീകരണവും വളരെ അത്യാവശ്യമായതുകൊണ്ടല്ല, ഏത് സാഹചര്യത്തിലും ഞങ്ങൾ പ്രകടനം ത്യജിക്കേണ്ടിവരും. എല്ലാം ലളിതമാണ് - ഇത് ശരിക്കും പ്രകടനത്തെ ബാധിക്കില്ല.

പ്രതിഫലന സാങ്കേതികവിദ്യയെ അടിസ്ഥാനമാക്കിയുള്ള ഏറ്റവും സാധാരണമായ ചട്ടക്കൂടുകൾ കൂടുതൽ മികച്ച രീതിയിൽ പ്രവർത്തിക്കാൻ എല്ലാത്തരം തന്ത്രങ്ങളും ഉപയോഗിക്കുന്നു എന്നതാണ് വസ്തുത. സാധാരണയായി ഇതൊരു കാഷെയാണ്. സാധാരണയായി ഇവ എക്സ്പ്രഷനുകളും ഡെലിഗേറ്റുകളും എക്സ്പ്രഷൻ ട്രീയിൽ നിന്ന് സമാഹരിച്ചവയാണ്. അതേ ഓട്ടോമാപ്പർ ഒരു മത്സര നിഘണ്ടു പരിപാലിക്കുന്നു, അത് പ്രതിഫലനത്തെ വിളിക്കാതെ തന്നെ മറ്റൊന്നിലേക്ക് പരിവർത്തനം ചെയ്യാൻ കഴിയുന്ന ഫംഗ്ഷനുകളുള്ള തരങ്ങളുമായി പൊരുത്തപ്പെടുന്നു.

ഇത് എങ്ങനെയാണ് നേടിയെടുക്കുന്നത്? അടിസ്ഥാനപരമായി, ഇത് JIT കോഡ് സൃഷ്ടിക്കാൻ പ്ലാറ്റ്ഫോം തന്നെ ഉപയോഗിക്കുന്ന യുക്തിയിൽ നിന്ന് വ്യത്യസ്തമല്ല. ഒരു രീതി ആദ്യമായി വിളിക്കുമ്പോൾ, അത് കംപൈൽ ചെയ്യപ്പെടുന്നു (അതെ, ഈ പ്രക്രിയ വേഗത്തിലല്ല); തുടർന്നുള്ള കോളുകളിൽ, ഇതിനകം കംപൈൽ ചെയ്ത രീതിയിലേക്ക് നിയന്ത്രണം കൈമാറ്റം ചെയ്യപ്പെടും, കൂടാതെ കാര്യമായ പ്രകടന കുറവുകളൊന്നും ഉണ്ടാകില്ല.

ഞങ്ങളുടെ കാര്യത്തിൽ, നിങ്ങൾക്ക് JIT കംപൈലേഷൻ ഉപയോഗിക്കാനും അതിന്റെ AOT എതിരാളികളുടെ അതേ പ്രകടനത്തോടെ കംപൈൽ ചെയ്ത സ്വഭാവം ഉപയോഗിക്കാനും കഴിയും. ഈ സാഹചര്യത്തിൽ എക്സ്പ്രഷനുകൾ ഞങ്ങളുടെ സഹായത്തിന് വരും.

സംശയാസ്പദമായ തത്വം ഇനിപ്പറയുന്ന രീതിയിൽ സംക്ഷിപ്തമായി രൂപപ്പെടുത്താം:
കംപൈൽ ചെയ്‌ത ഫംഗ്‌ഷൻ അടങ്ങുന്ന ഒരു ഡെലിഗേറ്റായി നിങ്ങൾ പ്രതിഫലനത്തിന്റെ അന്തിമ ഫലം കാഷെ ചെയ്യണം. ഒബ്‌ജക്‌റ്റുകൾക്ക് പുറത്ത് സംഭരിച്ചിരിക്കുന്ന നിങ്ങളുടെ തരത്തിലുള്ള, തൊഴിലാളിയുടെ ഫീൽഡുകളിൽ ടൈപ്പ് വിവരങ്ങൾ ഉപയോഗിച്ച് ആവശ്യമായ എല്ലാ ഒബ്‌ജക്റ്റുകളും കാഷെ ചെയ്യുന്നതും യുക്തിസഹമാണ്.

ഇതിൽ യുക്തിയുണ്ട്. എന്തെങ്കിലും കംപൈൽ ചെയ്യാനും കാഷെ ചെയ്യാനും കഴിയുമെങ്കിൽ അത് ചെയ്യണം എന്നാണ് സാമാന്യബുദ്ധി നമ്മോട് പറയുന്നത്.

മുന്നോട്ട് നോക്കുമ്പോൾ, നിങ്ങൾ എക്സ്പ്രഷനുകൾ കംപൈൽ ചെയ്യുന്നതിനുള്ള നിർദ്ദിഷ്ട രീതി ഉപയോഗിക്കുന്നില്ലെങ്കിലും, പ്രതിഫലനത്തിനൊപ്പം പ്രവർത്തിക്കുന്ന കാഷെയ്ക്ക് അതിന്റെ ഗുണങ്ങളുണ്ടെന്ന് പറയണം. യഥാർത്ഥത്തിൽ, ഞാൻ മുകളിൽ പരാമർശിച്ച ലേഖനത്തിന്റെ രചയിതാവിന്റെ തീസിസുകൾ ഇവിടെ ഞാൻ ആവർത്തിക്കുകയാണ്.

ഇപ്പോൾ കോഡിനെക്കുറിച്ച്. ഗുരുതരമായ ഒരു ക്രെഡിറ്റ് സ്ഥാപനത്തിന്റെ ഗുരുതരമായ നിർമ്മാണത്തിൽ എനിക്ക് നേരിടേണ്ടി വന്ന എന്റെ സമീപകാല വേദനയെ അടിസ്ഥാനമാക്കിയുള്ള ഒരു ഉദാഹരണം നോക്കാം. ആർക്കും ഊഹിക്കാൻ പറ്റാത്ത വിധത്തിൽ എല്ലാ സ്ഥാപനങ്ങളും സാങ്കൽപ്പികമാണ്.

കുറച്ച് സത്തയുണ്ട്. കോൺടാക്റ്റ് ഉണ്ടാകട്ടെ. ഒരു സ്റ്റാൻഡേർഡ് ബോഡി ഉള്ള അക്ഷരങ്ങളുണ്ട്, അതിൽ നിന്ന് പാർസറും ഹൈഡ്രേറ്ററും ഇതേ കോൺടാക്റ്റുകൾ സൃഷ്ടിക്കുന്നു. ഒരു കത്ത് വന്നു, ഞങ്ങൾ അത് വായിച്ചു, കീ-വാല്യൂ ജോഡികളായി പാഴ്‌സ് ചെയ്തു, ഒരു കോൺടാക്റ്റ് സൃഷ്ടിച്ച് ഡാറ്റാബേസിൽ സംരക്ഷിച്ചു.

അത് പ്രാഥമികമാണ്. ഒരു കോൺടാക്റ്റിന് പൂർണ്ണമായ പേര്, വയസ്സ്, കോൺടാക്റ്റ് ഫോൺ എന്നീ പ്രോപ്പർട്ടികൾ ഉണ്ടെന്ന് പറയാം. ഈ ഡാറ്റ കത്തിൽ കൈമാറുന്നു. കത്തിന്റെ ബോഡിയിൽ എന്റിറ്റി പ്രോപ്പർട്ടികൾ ജോഡികളായി മാപ്പുചെയ്യുന്നതിന് പുതിയ കീകൾ വേഗത്തിൽ ചേർക്കാൻ കഴിയുന്ന പിന്തുണയും ബിസിനസ്സ് ആഗ്രഹിക്കുന്നു. ടെംപ്ലേറ്റിൽ ആരെങ്കിലും അക്ഷരത്തെറ്റ് വരുത്തിയാൽ അല്ലെങ്കിൽ റിലീസിന് മുമ്പ് പുതിയ ഫോർമാറ്റിലേക്ക് പൊരുത്തപ്പെടുന്ന ഒരു പുതിയ പങ്കാളിയിൽ നിന്ന് അടിയന്തിരമായി മാപ്പിംഗ് സമാരംഭിക്കേണ്ടത് ആവശ്യമാണ്. അപ്പോൾ നമുക്ക് ഒരു വിലകുറഞ്ഞ ഡാറ്റാഫിക്സായി ഒരു പുതിയ മാപ്പിംഗ് കോറിലേഷൻ ചേർക്കാം. അതായത്, ഒരു ജീവിത മാതൃക.

ഞങ്ങൾ നടപ്പിലാക്കുന്നു, ടെസ്റ്റുകൾ സൃഷ്ടിക്കുന്നു. പ്രവർത്തിക്കുന്നു.

ഞാൻ കോഡ് നൽകില്ല: ധാരാളം ഉറവിടങ്ങളുണ്ട്, അവ ലേഖനത്തിന്റെ അവസാനത്തെ ലിങ്ക് വഴി GitHub-ൽ ലഭ്യമാണ്. നിങ്ങൾക്ക് അവരെ ലോഡുചെയ്യാനും തിരിച്ചറിയാൻ കഴിയാത്തവിധം പീഡിപ്പിക്കാനും അവയെ അളക്കാനും കഴിയും, അത് നിങ്ങളുടെ കാര്യത്തിൽ ബാധിക്കും. വേഗതയേറിയതായിരിക്കേണ്ട ഹൈഡ്രേറ്ററിനെ മന്ദഗതിയിലാക്കേണ്ട ഹൈഡ്രേറ്ററിൽ നിന്ന് വേർതിരിച്ചറിയുന്ന രണ്ട് ടെംപ്ലേറ്റ് രീതികളുടെ കോഡ് മാത്രമേ ഞാൻ തരൂ.

ലോജിക് ഇപ്രകാരമാണ്: ടെംപ്ലേറ്റ് രീതി അടിസ്ഥാന പാഴ്സർ ലോജിക് സൃഷ്ടിച്ച ജോഡികൾ സ്വീകരിക്കുന്നു. LINQ ലെയർ എന്നത് ഹൈഡ്രേറ്ററിന്റെ പാഴ്‌സറും അടിസ്ഥാന ലോജിക്കും ആണ്, ഇത് ഡാറ്റാബേസ് സന്ദർഭത്തിലേക്ക് ഒരു അഭ്യർത്ഥന നടത്തുകയും പാഴ്‌സറിൽ നിന്നുള്ള ജോഡികളുമായി കീകളെ താരതമ്യം ചെയ്യുകയും ചെയ്യുന്നു (ഈ ഫംഗ്‌ഷനുകൾക്ക് താരതമ്യത്തിനായി LINQ ഇല്ലാതെ കോഡ് ഉണ്ട്). അടുത്തതായി, ജോഡികളെ പ്രധാന ജലാംശം രീതിയിലേക്ക് മാറ്റുകയും ജോഡികളുടെ മൂല്യങ്ങൾ എന്റിറ്റിയുടെ അനുബന്ധ ഗുണങ്ങളിലേക്ക് സജ്ജീകരിക്കുകയും ചെയ്യുന്നു.

"വേഗത" (ബെഞ്ച്മാർക്കുകളിൽ ഫാസ്റ്റ് പ്രിഫിക്സ്):

 protected override Contact GetContact(PropertyToValueCorrelation[] correlations)
        {
            var contact = new Contact();
            foreach (var setterMapItem in _proprtySettersMap)
            {
                var correlation = correlations.FirstOrDefault(x => x.PropertyName == setterMapItem.Key);
                setterMapItem.Value(contact, correlation?.Value);
            }
            return contact;
        }

നമുക്ക് കാണാനാകുന്നതുപോലെ, സെറ്റർ പ്രോപ്പർട്ടികളുള്ള ഒരു സ്റ്റാറ്റിക് ശേഖരം ഉപയോഗിക്കുന്നു - സെറ്റർ എന്റിറ്റിയെ വിളിക്കുന്ന കംപൈൽഡ് ലാംഡാസ്. ഇനിപ്പറയുന്ന കോഡ് ഉപയോഗിച്ച് സൃഷ്‌ടിച്ചത്:

        static FastContactHydrator()
        {
            var type = typeof(Contact);
            foreach (var property in type.GetProperties())
            {
                _proprtySettersMap[property.Name] = GetSetterAction(property);
            }
        }

        private static Action<Contact, string> GetSetterAction(PropertyInfo property)
        {
            var setterInfo = property.GetSetMethod();
            var paramValueOriginal = Expression.Parameter(property.PropertyType, "value");
            var paramEntity = Expression.Parameter(typeof(Contact), "entity");
            var setterExp = Expression.Call(paramEntity, setterInfo, paramValueOriginal).Reduce();
            
            var lambda = (Expression<Action<Contact, string>>)Expression.Lambda(setterExp, paramEntity, paramValueOriginal);

            return lambda.Compile();
        }

പൊതുവേ, അത് വ്യക്തമാണ്. ഞങ്ങൾ പ്രോപ്പർട്ടികളിലൂടെ സഞ്ചരിക്കുന്നു, അവർക്കായി സെറ്റർമാരെ വിളിക്കുന്ന പ്രതിനിധികളെ സൃഷ്ടിക്കുകയും അവരെ സംരക്ഷിക്കുകയും ചെയ്യുന്നു. പിന്നെ ആവശ്യമുള്ളപ്പോൾ വിളിക്കും.

"സ്ലോ" (ബഞ്ച്മാർക്കുകളിൽ പ്രിഫിക്സ് സ്ലോ):

        protected override Contact GetContact(PropertyToValueCorrelation[] correlations)
        {
            var contact = new Contact();
            foreach (var property in _properties)
            {
                var correlation = correlations.FirstOrDefault(x => x.PropertyName == property.Name);
                if (correlation?.Value == null)
                    continue;

                property.SetValue(contact, correlation.Value);
            }
            return contact;
        }

ഇവിടെ ഞങ്ങൾ ഉടൻ തന്നെ പ്രോപ്പർട്ടികൾ മറികടന്ന് നേരിട്ട് SetValue എന്ന് വിളിക്കുന്നു.

വ്യക്തതയ്ക്കും ഒരു റഫറൻസ് എന്ന നിലയ്ക്കും, അവയുടെ പരസ്പര ബന്ധ ജോഡികളുടെ മൂല്യങ്ങൾ എന്റിറ്റി ഫീൽഡുകളിലേക്ക് നേരിട്ട് എഴുതുന്ന ഒരു നിഷ്കളങ്കമായ രീതി ഞാൻ നടപ്പിലാക്കി. പ്രിഫിക്സ് - മാനുവൽ.

ഇനി നമുക്ക് BenchmarkDotNet എടുത്ത് പ്രകടനം പരിശോധിക്കാം. പെട്ടെന്ന്... (സ്‌പോയിലർ - ഇത് ശരിയായ ഫലമല്ല, വിശദാംശങ്ങൾ ചുവടെ)

പ്രതിഫലനം ത്വരിതപ്പെടുത്തുന്നതിനെക്കുറിച്ചുള്ള ലേഖനം പരാജയപ്പെട്ടു

നമ്മൾ ഇവിടെ എന്താണ് കാണുന്നത്? ഫാസ്റ്റ് പ്രിഫിക്‌സ് വിജയകരമായി വഹിക്കുന്ന രീതികൾ സ്ലോ പ്രിഫിക്‌സ് ഉള്ള രീതികളേക്കാൾ മിക്കവാറും എല്ലാ പാസുകളിലും വേഗത കുറവാണ്. ജോലിയുടെ വിഹിതത്തിനും വേഗതയ്ക്കും ഇത് ശരിയാണ്. മറുവശത്ത്, സാധ്യമാകുന്നിടത്തെല്ലാം ഉദ്ദേശിച്ചിട്ടുള്ള LINQ രീതികൾ ഉപയോഗിച്ച് മാപ്പിംഗ് മനോഹരവും ഗംഭീരവുമായ നടപ്പിലാക്കൽ, മറിച്ച്, ഉൽപ്പാദനക്ഷമതയെ വളരെയധികം കുറയ്ക്കുന്നു. വ്യത്യാസം ക്രമത്തിലാണ്. വ്യത്യസ്‌ത പാസുകൾ ഉപയോഗിച്ച് ട്രെൻഡ് മാറില്ല. വ്യത്യാസം സ്കെയിലിൽ മാത്രമാണ്. LINQ-ൽ ഇത് 4 - 200 മടങ്ങ് മന്ദഗതിയിലാണ്, ഏകദേശം ഒരേ സ്കെയിലിൽ കൂടുതൽ മാലിന്യങ്ങൾ ഉണ്ട്.

UPDATED

ഞാൻ എന്റെ കണ്ണുകളെ വിശ്വസിച്ചില്ല, അതിലും പ്രധാനമായി, ഞങ്ങളുടെ സഹപ്രവർത്തകൻ എന്റെ കണ്ണുകളോ എന്റെ കോഡോ വിശ്വസിച്ചില്ല - ദിമിത്രി ടിഖോനോവ് 0x1000000. എന്റെ സൊല്യൂഷൻ രണ്ടുതവണ പരിശോധിച്ച ശേഷം, പ്രാരംഭം മുതൽ അന്തിമം വരെയുള്ള നടപ്പാക്കലിലെ നിരവധി മാറ്റങ്ങൾ കാരണം എനിക്ക് നഷ്‌ടമായ ഒരു പിശക് അദ്ദേഹം സമർത്ഥമായി കണ്ടെത്തുകയും ചൂണ്ടിക്കാണിക്കുകയും ചെയ്തു. Moq സജ്ജീകരണത്തിൽ കണ്ടെത്തിയ ബഗ് പരിഹരിച്ചതിന് ശേഷം, എല്ലാ ഫലങ്ങളും പ്രാബല്യത്തിൽ വന്നു. റീടെസ്റ്റ് ഫലങ്ങൾ അനുസരിച്ച്, പ്രധാന പ്രവണത മാറില്ല - പ്രതിഫലനത്തേക്കാൾ പ്രകടനത്തെ LINQ ഇപ്പോഴും ബാധിക്കുന്നു. എന്നിരുന്നാലും, എക്സ്പ്രഷൻ കംപൈലേഷനുമൊത്തുള്ള ജോലി വെറുതെ ചെയ്യാത്തത് സന്തോഷകരമാണ്, കൂടാതെ അലോക്കേഷനിലും എക്സിക്യൂഷൻ സമയത്തിലും ഫലം ദൃശ്യമാണ്. സ്റ്റാറ്റിക് ഫീൽഡുകൾ ആരംഭിക്കുമ്പോൾ ആദ്യ വിക്ഷേപണം "ഫാസ്റ്റ്" രീതിക്ക് സ്വാഭാവികമായും മന്ദഗതിയിലാണ്, എന്നാൽ പിന്നീട് സ്ഥിതി മാറുന്നു.

വീണ്ടും പരീക്ഷയുടെ ഫലം ഇതാ:

പ്രതിഫലനം ത്വരിതപ്പെടുത്തുന്നതിനെക്കുറിച്ചുള്ള ലേഖനം പരാജയപ്പെട്ടു

ഉപസംഹാരം: ഒരു എന്റർപ്രൈസസിൽ പ്രതിഫലനം ഉപയോഗിക്കുമ്പോൾ, പ്രത്യേക തന്ത്രങ്ങൾ അവലംബിക്കേണ്ട ആവശ്യമില്ല - LINQ ഉൽപ്പാദനക്ഷമതയെ കൂടുതൽ തിന്നുതീർക്കും. എന്നിരുന്നാലും, ഒപ്റ്റിമൈസേഷൻ ആവശ്യമുള്ള ഉയർന്ന-ലോഡ് രീതികളിൽ, നിങ്ങൾക്ക് ഇനീഷ്യലൈസറുകളുടെയും ഡെലിഗേറ്റ് കംപൈലറുകളുടെയും രൂപത്തിൽ പ്രതിഫലനം സംരക്ഷിക്കാൻ കഴിയും, അത് "ഫാസ്റ്റ്" ലോജിക് നൽകും. ഇതുവഴി നിങ്ങൾക്ക് പ്രതിഫലനത്തിന്റെ വഴക്കവും ആപ്ലിക്കേഷന്റെ വേഗതയും നിലനിർത്താൻ കഴിയും.

ബെഞ്ച്മാർക്ക് കോഡ് ഇവിടെ ലഭ്യമാണ്. എന്റെ വാക്കുകൾ ആർക്കും രണ്ടുതവണ പരിശോധിക്കാം:
ഹബ്ര റിഫ്ലക്ഷൻ ടെസ്റ്റുകൾ

PS: ടെസ്റ്റുകളിലെ കോഡ് IoC ഉപയോഗിക്കുന്നു, കൂടാതെ ബെഞ്ച്മാർക്കുകളിൽ ഇത് ഒരു വ്യക്തമായ നിർമ്മാണം ഉപയോഗിക്കുന്നു. അന്തിമ നിർവ്വഹണത്തിൽ പ്രകടനത്തെ ബാധിക്കുകയും ഫലം ശബ്ദമുണ്ടാക്കുകയും ചെയ്യുന്ന എല്ലാ ഘടകങ്ങളും ഞാൻ വെട്ടിക്കളഞ്ഞു എന്നതാണ് വസ്തുത.

PPS: ഉപയോക്താവിന് നന്ദി ദിമിത്രി ടിഖോനോവ് @0x1000000 Moq സജ്ജീകരിക്കുന്നതിൽ എന്റെ പിശക് കണ്ടെത്തിയതിന്, ഇത് ആദ്യ അളവുകളെ ബാധിച്ചു. വായനക്കാരിൽ ആർക്കെങ്കിലും മതിയായ കർമ്മമുണ്ടെങ്കിൽ, ദയവായി ലൈക്ക് ചെയ്യുക. ആൾ നിർത്തി, ആ മനുഷ്യൻ വായിച്ചു, ആ മനുഷ്യൻ രണ്ടുതവണ പരിശോധിച്ച് തെറ്റ് ചൂണ്ടിക്കാണിച്ചു. ഇത് ബഹുമാനത്തിനും സഹതാപത്തിനും അർഹമാണെന്ന് ഞാൻ കരുതുന്നു.

PPPS: ശൈലിയുടെയും രൂപകൽപ്പനയുടെയും അടിത്തട്ടിൽ എത്തിയ സൂക്ഷ്മ വായനക്കാരന് നന്ദി. ഞാൻ ഏകതാനതയ്ക്കും സൗകര്യത്തിനും വേണ്ടിയാണ്. അവതരണത്തിന്റെ നയതന്ത്രം ആഗ്രഹിക്കാവുന്ന പലതും അവശേഷിക്കുന്നു, പക്ഷേ ഞാൻ വിമർശനം കണക്കിലെടുക്കുന്നു. ഞാൻ പ്രൊജക്റ്റൈൽ ആവശ്യപ്പെടുന്നു.

അവലംബം: www.habr.com

ഒരു അഭിപ്രായം ചേർക്കുക