ነጸብራቅን ስለማፋጠን ያልተሳካ መጣጥፍ

ወዲያውኑ የጽሁፉን ርዕስ እገልጻለሁ. የመጀመሪያው እቅድ ቀላል ነገር ግን ተጨባጭ ምሳሌን በመጠቀም የማሰላሰል አጠቃቀምን እንዴት ማፋጠን እንዳለብን ጥሩ እና አስተማማኝ ምክር ለመስጠት ነበር ነገርግን በቤንችማርክ ወቅት ማሰላሰሉ እንዳሰብኩት ቀርፋፋ እንዳልሆነ LINQ ከቅዠቴ ቀርፋፋ ነው። በመጨረሻ ግን በመለኪያዎች ላይም ስህተት እንደሰራሁ ታወቀ ... የዚህ የህይወት ታሪክ ዝርዝር መግለጫዎች እና አስተያየቶች ውስጥ ይገኛሉ ። ምሳሌው በጣም የተለመደ እና በድርጅት ውስጥ እንደሚደረገው በመርህ ደረጃ የሚተገበር በመሆኑ ፣ ለእኔ እንደሚመስለኝ ​​፣ የህይወት ማሳያ ሆኖ በጣም አስደሳች ሆኖ ተገኝቷል - በአንቀጹ ዋና ርዕሰ ጉዳይ ላይ ያለው ተፅእኖ። በውጫዊ ሎጂክ ምክንያት የማይታወቅ: Moq, Autofac, EF Core እና ሌሎች "ባንዲንግ".

በዚህ ጽሑፍ ስሜት መሥራት ጀመርኩ፡- ለምን ነፀብራቅ ቀርፋፋ ነው።

እርስዎ እንደሚመለከቱት ደራሲው አፕሊኬሽኑን በከፍተኛ ሁኔታ ለማፋጠን እንደ ትልቅ መንገድ በቀጥታ የነጸብራቅ ዓይነት ዘዴዎችን ከመጥራት ይልቅ የተጠናቀሩ ልዑካንን መጠቀምን ይጠቁማል። በእርግጥ የ IL ልቀት አለ, ነገር ግን ይህ በስህተት የተሞላው ስራውን ለማከናወን በጣም ጉልበት የሚጠይቅ መንገድ ስለሆነ እሱን ማስወገድ እፈልጋለሁ.

ስለ ነጸብራቅ ፍጥነት ሁሌም ተመሳሳይ አስተያየት እንደያዝኩ ግምት ውስጥ በማስገባት የጸሐፊውን መደምደሚያ ለመጠራጠር አላሰብኩም።

በኢንተርፕራይዙ ውስጥ ብዙ ጊዜ የዋህ የማሰላሰል አጠቃቀም ያጋጥመኛል። ዓይነት ይወሰዳል. ስለ ንብረቱ መረጃ ይወሰዳል. የ SetValue ዘዴ ተጠርቷል እና ሁሉም ሰው ይደሰታል። እሴቱ በዒላማው መስክ ላይ ደርሷል, ሁሉም ሰው ደስተኛ ነው. በጣም ብልህ ሰዎች - አዛውንቶች እና የቡድን መሪዎች - ቅጥያዎቻቸውን ለመቃወም ይጽፋሉ ፣ እንደዚህ ባለ “ሁለንተናዊ” የአንዱ ዓይነት ወደ ሌላ ዓይነት ካርታዎች ላይ በመመስረት። ዋናው ነገር ብዙውን ጊዜ ይህ ነው-ሁሉንም መስኮች እንወስዳለን, ሁሉንም ንብረቶች እንወስዳለን, በእነሱ ላይ ደጋግመን እንሰራለን: የአባላቱ ስሞች ከተዛመዱ, SetValue እንፈጽማለን. ከጊዜ ወደ ጊዜ ከአንዱ ዓይነቶች ውስጥ አንዳንድ ንብረቶችን ባላገኘንበት ስህተቶች ምክንያት ልዩ ሁኔታዎችን እንይዛለን ፣ ግን እዚህ እንኳን አፈፃፀምን የሚያሻሽል መውጫ መንገድ አለ። ይሞክሩ/ያዙ።

ሰዎች ከነሱ በፊት የነበሩት ማሽኖች እንዴት እንደሚሰሩ መረጃ ሳይታጠቁ ተንታኞችን እና ካርታዎችን እንደገና ሲፈጥሩ አይቻለሁ። ይህ ተከታዩን ባካናሊያን ሰበብ የሚያደርግ መስሎ ሰዎች ከስልቶች፣ ከመገናኛዎች በስተጀርባ፣ በመርፌ መወጋት ጀርባ ያላቸውን የዋህ አተገባበር ሲደብቁ አይቻለሁ። በእንደዚህ ዓይነት ግንዛቤዎች አፍንጫዬን አነሳሁ። በእውነቱ፣ የእውነተኛውን የአፈጻጸም ፍሰት አልለካም፣ እና ከተቻለ በቀላሉ እጄን ማግኘት ከቻልኩ አተገባበሩን ወደ “ምርጥ” ቀይሬዋለሁ። ስለዚህ፣ ከዚህ በታች የተብራሩት የመጀመሪያዎቹ መለኪያዎች ግራ አጋባኝ።

እኔ እንደማስበው ብዙዎቻችሁ፣ ሪችተር ወይም ሌሎች የርዕዮተ ዓለም ምሁራን፣ በኮድ ውስጥ ማሰላሰል በመተግበሪያው አፈጻጸም ላይ እጅግ በጣም አሉታዊ ተፅእኖ ያለው ክስተት ነው የሚል ፍጹም ፍትሃዊ መግለጫ ያጋጠማችሁ።

ነጸብራቅን መጥራት CLR የሚያስፈልጋቸውን ለማግኘት፣ ዲበ ዳታቸውን ለማውጣት፣ እንዲተነተን፣ ወዘተ እንዲፈልጉ በስብሰባዎች ውስጥ እንዲያልፍ ያስገድዳቸዋል። በተጨማሪም, ቅደም ተከተሎችን በሚያልፉበት ጊዜ ማሰላሰል ከፍተኛ መጠን ያለው ማህደረ ትውስታን ወደ መመደብ ይመራል. ማህደረ ትውስታን እየተጠቀምን ነው፣ CLR GCን ይከፍታል እና ፍሪዝስ ይጀምራል። በሚያስደንቅ ሁኔታ ቀርፋፋ መሆን አለበት ፣ እመኑኝ። በዘመናዊ የማምረቻ ሰርቨሮች ወይም የደመና ማሽኖች ላይ ያለው ከፍተኛ መጠን ያለው የማስታወስ ችሎታ ከፍተኛ ሂደት መዘግየትን አይከለክልም። እንዲያውም፣ የማስታወስ ችሎታው እየጨመረ በሄደ መጠን GC እንዴት እንደሚሰራ የማሳወቅ ዕድሉ ይጨምራል። ነጸብራቅ, በንድፈ ሀሳብ, ለእሱ ተጨማሪ ቀይ ጨርቅ ነው.

ይሁን እንጂ ሁላችንም የ IoC ኮንቴይነሮችን እና የቀን ካርታዎችን እንጠቀማለን, የአሠራሩ መርህ እንዲሁ በማንፀባረቅ ላይ የተመሰረተ ነው, ነገር ግን በአብዛኛው ስለ አፈፃፀማቸው ምንም ጥያቄዎች የሉም. አይደለም፣ ምክንያቱም ጥገኞችን ማስተዋወቅ እና ከውጫዊ ውሱን አውድ ሞዴሎች ረቂቅነት በጣም አስፈላጊ ስለሆኑ በማንኛውም ሁኔታ አፈጻጸምን መስዋዕት ማድረግ አለብን። ሁሉም ነገር ቀላል ነው - በእውነቱ በአፈፃፀም ላይ ብዙም ተጽዕኖ አያሳድርም።

እውነታው ግን በአንጸባራቂ ቴክኖሎጂ ላይ የተመሰረቱት በጣም የተለመዱት ማዕቀፎች ከእሱ ጋር በተሻለ ሁኔታ ለመስራት ሁሉንም አይነት ዘዴዎች ይጠቀማሉ. ብዙውን ጊዜ ይህ መሸጎጫ ነው። በተለምዶ እነዚህ መግለጫዎች እና ልዑካን ከመግለጫው ዛፍ የተሰባሰቡ ናቸው። ተመሳሳዩ አውቶማፐር ነጸብራቅ ሳይጠሩ አንዱን ወደ ሌላ ሊለውጡ ከሚችሉ ተግባራት ጋር የሚዛመድ ተወዳዳሪ መዝገበ ቃላት ይይዛል።

ይህ እንዴት ሊገኝ ቻለ? በመሠረቱ, ይህ መድረክ ራሱ 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 ጊዜ ቀርፋፋ ነው ፣ በተመሳሳይ ሚዛን ላይ ብዙ ቆሻሻዎች አሉ።

የተዘመነ

ዓይኖቼን አላመንኩም ነበር ፣ ግን ከሁሉም በላይ ፣ ባልደረባችን ዓይኖቼን ወይም ኮዴን አላመነም - ዲሚትሪ ቲኮኖቭ 0x1000000. የመፍትሄዬን ሁለቴ ካጣራ በኋላ፣ በግሩም ሁኔታ አግኝቼው የነበረኝን ስህተት ከመነሻ እስከ መጨረሻው ባሉት በርካታ ለውጦች ምክንያት ያመለጠኝን ስህተት ጠቁሟል። በሞክ ማዋቀር ውስጥ የተገኘውን ስህተት ካስተካከለ በኋላ ሁሉም ውጤቶች ወደ ቦታው ወድቀዋል። በድጋሚ ሙከራው መሠረት ዋናው አዝማሚያ አይለወጥም - LINQ አሁንም ከማንፀባረቅ የበለጠ አፈፃፀም ላይ ተጽዕኖ ያሳድራል። ሆኖም ፣ ከ Expression ማጠናቀር ጋር ያለው ሥራ በከንቱ አለመከናወኑ ጥሩ ነው ፣ ውጤቱም በምደባ እና በአፈፃፀም ጊዜ ይታያል። የመጀመሪያው ጅምር፣ የማይለዋወጡ መስኮች ሲጀምሩ፣ ለ "ፈጣን" ዘዴ በተፈጥሮ ቀርፋፋ ነው፣ ነገር ግን ሁኔታው ​​ይለወጣል።

የድጋሚ ሙከራው ውጤት እነሆ፡-

ነጸብራቅን ስለማፋጠን ያልተሳካ መጣጥፍ

ማጠቃለያ-በኢንተርፕራይዝ ውስጥ ነጸብራቅ ሲጠቀሙ ልዩ ዘዴዎችን መጠቀም አያስፈልግም - LINQ ምርታማነትን የበለጠ ይበላል ። ነገር ግን, ማመቻቸትን በሚያስፈልጋቸው ከፍተኛ ጭነት ዘዴዎች ውስጥ ነጸብራቅን በመነሻዎች እና በተወካዮች መልክ ማስቀመጥ ይችላሉ, ይህም "ፈጣን" አመክንዮ ያቀርባል. በዚህ መንገድ ሁለቱንም የማንፀባረቅ ተለዋዋጭነት እና የመተግበሪያውን ፍጥነት ማቆየት ይችላሉ.

የቤንችማርክ ኮድ እዚህ አለ። ማንም ሰው ቃሎቼን በድጋሚ ማረጋገጥ ይችላል፡-
የሀብራ ነጸብራቅ ሙከራዎች

PS፡ በፈተናዎች ውስጥ ያለው ኮድ IoCን ይጠቀማል፣ እና በማመሳከሪያዎቹ ውስጥ ግልጽ የሆነ ግንባታ ይጠቀማል። እውነታው ግን በመጨረሻው አተገባበር ላይ በአፈፃፀም ላይ ተጽዕኖ ሊያሳርፉ የሚችሉትን ሁሉንም ነገሮች አቋርጣለሁ እና ውጤቱን ጫጫታ ያደርገዋል.

ፒፒኤስ፡ ለተጠቃሚው አመሰግናለሁ ዲሚትሪ Tikhonov @0x1000000 የመጀመሪያዎቹን መለኪያዎች የነካውን ሞክን በማዘጋጀት ላይ ስህተቴን ለማወቅ። አንባቢዎቹ በቂ ካርማ ካላቸው እባክዎን ይውደዱ። ሰውዬው ቆመ፣ ሰውየው አነበበ፣ ሰውየው ሁለት ጊዜ ፈትሸው ስህተቱን ገለጸ። ይህ መከባበር እና መተሳሰብ የሚገባው ይመስለኛል።

ፒፒፒኤስ፡ በቅጡ እና በንድፍ ስር ላገኘው አስተዋይ አንባቢ አመሰግናለሁ። እኔ ለአንድነት እና ለመመቻቸት ነኝ። የአቀራረብ ዲፕሎማሲው ብዙ የሚፈለግ ቢሆንም እኔ ግን ትችቱን ግምት ውስጥ ያስገባሁት። ፕሮጀክቱን እጠይቃለሁ.

ምንጭ: hab.com

አስተያየት ያክሉ