મેં માત્ર ફેંકી દેવા માટે 7.8 MB કી ફાળવી દીધી
એક પ્રોફાઇલરે મારા કોડમાં રહેલા છુપાયેલા ખર્ચને ખુલ્લો પાડ્યો.
મારો request handler એક વિશાળ string માંથી tokens વાંચે છે અને તેમના weights નો સરવાળો કરે છે. લોજિક કામ કરતું હતું, પણ મેમરી નહીં.
એક hot loop ની અંદર મેં 7.8 MB strings ફાળવી હતી—દરેક dictionary lookup માટે એક નવી key—અને પછી તરત જ તે key ફેંકી દીધી હતી.
આનું કારણ Substring હતું. દરેક slice એક નવી string object બનાવતું હતું.
200,000 tokens
- Method A (Substring): 23.4 ms, 7,812 KB allocated.
- Method B (Span Lookup): 14.9 ms, 0 KB allocated.
Method B 1.5x ઝડપથી ચાલે છે અને કોઈ garbage પેદા કરતું નથી.
.NET 9 માં તમે GetAlternateLookup ને કોલ કરી શકો છો. નવી string ને બદલે, તમે ReadOnlySpan<char> પાસ કરી શકો છો, જે મૂળ string પર માત્ર એક window જેવું છે—કોઈ copying વગર.
Dictionary span ને સીધું જ હાલની keys સામે hash કરે છે, જેનાથી કોઈ allocation વગર સમાન પરિણામ મળે છે.
યાદ રાખવા જેવી બાબતો
StringComparer.OrdinalઅનેStringComparer.OrdinalIgnoreCaseસાથે કામ કરે છે.- જો તમે એવો custom comparer વાપરો જેમાં alternate lookup સપોર્ટ ન હોય, તો તે runtime પર error ફેંકે છે.
- Parsers, log processors, અથવા CSV scanners જેવા hot paths માટે આદર્શ છે.
- માત્ર થોડી જ keys ધરાવતા સાદા lookups માટે આનો ઉપયોગ ટાળો.
હવે હું મારા કોડમાં Substring પછી TryGetValue હોય તેવા પેટર્ન શોધું છું. તે પેટર્ન મેમરીનો મોટો બગાડ કરે છે.
સ્ત્રોત: https://dev.to/ssukhpinder/78-mb-of-keys-i-allocated-just-to-throw-away-50mn
વૈકલ્પિક લર્નિંગ કોમ્યુનિટી: https://github.com/ssukhpinder/dev-to-code-samples/tree/main/023-dictionary-alternate-lookup
