.NET teljesítményhangolási tapasztalatok 1.

Volt egy munkám, amiben egy bonyolult formokat dinamikusan, xml leírásból megjelenítő üzleti alkalmazást kellett optimalizálni.
A probléma az volt vele, hogy a formokat nagyon lassan generálta le, 10-20 mp is kellett egy bonyolultabbhoz. Ezeken már több száz vezérlő volt, de akkor is, nem kell annak ilyen lassúnak lenni.
A szűk keresztmetszetek felderítéséhez a korábbi bejegyzésben említett VSTS profilert használtam.
A következő általánosítható tapasztalatokról számolhatok be. Mivel nagyon sok érdekes eredménye volt a kutatásnak, több részben osztom ezeket meg veletek.

Ha nem használjuk ki a ResourceManager lokalizálási lehetőségeit, csak arra használunk erőforrásokat, hogy a kódból kiemeljünk egyes, később esetleg módosítandó stringeket, akkor sokat sprórolhatunk az erőforrások betöltésekor.
Példaképpen nézzünk egy sima WinForms alkalmazást, amihez hozzáadtunk egy erőforrást (.resx). A resxhez generálnak nekünk egy típusos elérő osztályt is, így a következő sorral egyszerűen elérhetjük az erőforrásként tárolt Teszt nevű kulcsot:


MessageBox.Show(Resource1.Teszt);

Mit is csinál a generált kód?


internal static string Teszt
{
    get
    {
        return ResourceManager.GetString("Teszt", resourceCulture);
    }
}

Ahol a ResourceManager egy System.Resources.ResourceManager példány.

Az ő feladata, hogy megpróbáljon lokalizált erőforrásokat keresni, ha vannak, azokat betölteni. Hol laknak ezek? Processz Explorerrel megnézve kiderül:


CultureTest.exe	FAST IO DISALLOWED	C:\szemet\CultureTest\bin\Debug\en-US\CultureTest.resources.dll
CultureTest.exe	PATH NOT FOUND	C:\szemet\CultureTest\bin\Debug\en-US\CultureTest.resources.dll
CultureTest.exe	FAST IO DISALLOWED	C:\szemet\CultureTest\bin\Debug\en-US\CultureTest.resources\CultureTest.resources.dll
CultureTest.exe	PATH NOT FOUND	C:\szemet\CultureTest\bin\Debug\en-US\CultureTest.resources\CultureTest.resources.dll
CultureTest.exe	FAST IO DISALLOWED	C:\szemet\CultureTest\bin\Debug\en-US\CultureTest.resources.exe
CultureTest.exe	PATH NOT FOUND	C:\szemet\CultureTest\bin\Debug\en-US\CultureTest.resources.exe
CultureTest.exe	FAST IO DISALLOWED	C:\szemet\CultureTest\bin\Debug\en-US\CultureTest.resources\CultureTest.resources.exe
CultureTest.exe	PATH NOT FOUND	C:\szemet\CultureTest\bin\Debug\en-US\CultureTest.resources\CultureTest.resources.exe
CultureTest.exe	FAST IO DISALLOWED	C:\Windows\Microsoft.NET\Framework\v2.0.50727\en-US\mscorrc.dll
CultureTest.exe	PATH NOT FOUND	C:\Windows\Microsoft.NET\Framework\v2.0.50727\en-US\mscorrc.dll
CultureTest.exe	FAST IO DISALLOWED	C:\Windows\Microsoft.NET\Framework\v2.0.50727\en-US\mscorrc.dll
CultureTest.exe	PATH NOT FOUND	C:\Windows\Microsoft.NET\Framework\v2.0.50727\en-US\mscorrc.dll
CultureTest.exe	FAST IO DISALLOWED	C:\Windows\Microsoft.NET\Framework\v2.0.50727\en-US\mscorrc.dll.DLL
CultureTest.exe	PATH NOT FOUND	C:\Windows\Microsoft.NET\Framework\v2.0.50727\en-US\mscorrc.dll.DLL
CultureTest.exe	FAST IO DISALLOWED	C:\Windows\Microsoft.NET\Framework\v2.0.50727\en\mscorrc.dll
CultureTest.exe	NAME NOT FOUND	C:\Windows\Microsoft.NET\Framework\v2.0.50727\en\mscorrc.dll
CultureTest.exe	FAST IO DISALLOWED	C:\Windows\Microsoft.NET\Framework\v2.0.50727\en\mscorrc.dll
CultureTest.exe	NAME NOT FOUND	C:\Windows\Microsoft.NET\Framework\v2.0.50727\en\mscorrc.dll
CultureTest.exe	FAST IO DISALLOWED	C:\Windows\Microsoft.NET\Framework\v2.0.50727\en\mscorrc.dll.DLL
CultureTest.exe	NAME NOT FOUND	C:\Windows\Microsoft.NET\Framework\v2.0.50727\en\mscorrc.dll.DLL
CultureTest.exe	FAST IO DISALLOWED	C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll
CultureTest.exe	SUCCESS	C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll

Szép lista, mi? És nem is mindig ilyen rövid a lista, sok assembly és több alkönyvtár is be szokott jönni a képbe. Szóval ő keresgélt keményen, mire a végén rájött (ez nem látszik az előbbiből), hogy a fő assemblyben, a CultureTest.exe-ben van, amiért küzd. Ez a fallback location.
Mellesleg a rémségek kicsiny tárháza nem merül ki ennyiben. Nézzük meg, mi történt a registryben:


2	CultureTest.exe	RegOpenKey	NAME NOT FOUND	Desired Access: Read	HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\Managed\S-1-5-21-1912844993-3366795750-3477756003-1000\Installer\Assemblies\C:|szemet|CultureTest|bin|Debug|CultureTest.exe
3	CultureTest.exe	RegOpenKey	NAME NOT FOUND	Desired Access: Read	HKCU\Software\Microsoft\Installer\Assemblies\C:|szemet|CultureTest|bin|Debug|CultureTest.exe
4	CultureTest.exe	RegOpenKey	NAME NOT FOUND	Desired Access: Read	HKCR\Installer\Assemblies\C:|szemet|CultureTest|bin|Debug|CultureTest.exe
5	CultureTest.exe	RegOpenKey	NAME NOT FOUND	Desired Access: Read	HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\Managed\S-1-5-21-1912844993-3366795750-3477756003-1000\Installer\Assemblies\Global
6	CultureTest.exe	RegOpenKey	SUCCESS	Desired Access: Read	HKCU\Software\Microsoft\Installer\Assemblies\Global
7	CultureTest.exe	RegEnumValue	SUCCESS	Index: 0, Name: System.Data.Entity,version="3.5.0.0",publicKeyToken="b77a5c561934e089",processorArchitecture="MSIL",fileVersion="3.5.21015.1",culture="neutral", Type: REG_MULTI_SZ, Length: 126, Data: C3OujdJLp9NfYy,t(d,[DP_EntityFramework_F>XQM@Z1Phc9}TW]UlV1Ni	HKCU\Software\Microsoft\Installer\Assemblies\Global
8	CultureTest.exe	RegEnumValue	SUCCESS	Index: 1, Name: System.Data.Entity.Design,version="3.5.0.0",publicKeyToken="b77a5c561934e089",processorArchitecture="MSIL",fileVersion="3.5.21015.1",culture="neutral", Type: REG_MULTI_SZ, Length: 126, Data: C3OujdJLp9NfYy,t(d,[DP_EntityFramework_F>rl{^k~VBe8%[-9p_{$g7	HKCU\Software\Microsoft\Installer\Assemblies\Global
9	CultureTest.exe	RegEnumValue	SUCCESS	Index: 2, Name: System.Windows.Forms.DataVisualization,version="3.5.0.0",publicKeyToken="31bf3856ad364e35",processorArchitecture="MSIL",fileVersion="3.5.30729.116",culture="neutral", Type: REG_MULTI_SZ, Length: 112, Data: O`X&9fQNo8q+=[WOk(@QChart_Feature>v'=bOR[V[A!n0Y5w^}Hc	HKCU\Software\Microsoft\Installer\Assemblies\Global
10	CultureTest.exe	RegEnumValue	SUCCESS	Index: 3, Name: System.Windows.Forms.DataVisualization.Design,version="3.5.0.0",publicKeyToken="31bf3856ad364e35",processorArchitecture="MSIL",fileVersion="3.5.30729.116",culture="neutral", Type: REG_MULTI_SZ, Length: 112, Data: O`X&9fQNo8q+=[WOk(@QChart_Feature>i_^,7P9r9@brsnF$'^Sq	HKCU\Software\Microsoft\Installer\Assemblies\Global
11	CultureTest.exe	RegEnumValue	SUCCESS	Index: 4, Name: System.Web.DataVisualization,version="3.5.0.0",publicKeyToken="31bf3856ad364e35",processorArchitecture="MSIL",fileVersion="3.5.30729.116",culture="neutral", Type: REG_MULTI_SZ, Length: 112, Data: O`X&9fQNo8q+=[WOk(@QChart_Feature>Wh{mN1!@0AM{uwUXeK*Y	HKCU\Software\Microsoft\Installer\Assemblies\Global
12	CultureTest.exe	RegEnumValue	SUCCESS	Index: 5, Name: System.Web.DataVisualization.Design,version="3.5.0.0",publicKeyToken="31bf3856ad364e35",processorArchitecture="MSIL",fileVersion="3.5.30729.116",culture="neutral", Type: REG_MULTI_SZ, Length: 112, Data: O`X&9fQNo8q+=[WOk(@QChart_Feature>)s9`q)4`i?zUn`)KOc8c	HKCU\Software\Microsoft\Installer\Assemblies\Global
13	CultureTest.exe	RegEnumValue	NO MORE ENTRIES	Index: 6, Length: 4,168	HKCU\Software\Microsoft\Installer\Assemblies\Global
14	CultureTest.exe	RegCloseKey	SUCCESS		HKCU\Software\Microsoft\Installer\Assemblies\Global
15	CultureTest.exe	RegOpenKey	SUCCESS	Desired Access: Read	HKCR\Installer\Assemblies\Global
16	CultureTest.exe	RegEnumValue	SUCCESS	Index: 0, Name: Microsoft.VisualStudio.VSContentInstaller,Version="8.0.0.0",PublicKeyToken="b03f5f7f11d50a3a",Culture="neutral",FileVersion="8.0.50727.42",ProcessorArchitecture="MSIL", Type: REG_MULTI_SZ, Length: 404, Data: Du!zKukZ[8DDoq4qr00M>IEJ5Ceoex8F3H%MC+Ga*, gKH-=4wv49{b[v2]HUCqDEXPLORE>IEJ5Ceoex8F3H%MC+Ga*, UvOAm{qpx?)oAC'mF&N`VSTA_IDE>IEJ5Ceoex8F3H%MC+Ga*, ^Sd&qu_%!Ajz=c-67LgzVS_Baseline_Shell>IEJ5Ceoex8F3H%MC+Ga*	HKCR\Installer\Assemblies\Global
17	CultureTest.exe	RegEnumValue	SUCCESS	Index: 1, Name: Microsoft.VisualStudio.Zip,Version="8.0.0.0",PublicKeyToken="b03f5f7f11d50a3a",Culture="neutral",FileVersion="8.0.50727.42",ProcessorArchitecture="MSIL", Type: REG_MULTI_SZ, Length: 708, Data: Du!zKukZ[8DDoq4qr00M>gOxADwX'$9kl'.`[S7hE, Du!zKukZ[8DDoq4qr00M>O%ZhVgKv@A4B`u_Z?tGQ, gKH-=4wv49{b[v2]HUCqDEXPLORE>gOxADwX'$9kl'.`[S7hE, gKH-=4wv49{b[v2]HUCqDEXPLORE>O%ZhVgKv@A4B`u_Z?tGQ, UvOAm{qpx?)oAC'mF&N`VSTA_IDE_Resources>gOxADwX'$9kl'.`[S7hE, UvOAm{qpx?)oAC'mF&N`VSTA_IDE>O%ZhVgKv@A4B`u_Z?tGQ, ^Sd&qu_%!Ajz=c-67LgzVS_Baseline_Shell>gOxADwX'$9kl'.`[S7hE	HKCR\Installer\Assemblies\Global
18	CultureTest.exe	RegEnumValue	SUCCESS	Index: 2, Name: Microsoft.VisualStudio.CommonIDE,Version="8.0.0.0",PublicKeyToken="b03f5f7f11d50a3a",Culture="neutral",FileVersion="8.0.50727.42",ProcessorArchitecture="MSIL", Type: REG_MULTI_SZ, Length: 286, Data: Du!zKukZ[8DDoq4qr00M>vpAcaJ2Wn@5ip,X!wCW!, gKH-=4wv49{b[v2]HUCqDEXPLORE>vpAcaJ2Wn@5ip,X!wCW!, UvOAm{qpx?)oAC'mF&N`VSTA_IDE>vpAcaJ2Wn@5ip,X!wCW!	HKCR\Installer\Assemblies\Global
19	CultureTest.exe	RegEnumValue	SUCCESS	Index: 3, Name: EnvDTE,Version="8.0.0.0",PublicKeyToken="b03f5f7f11d50a3a",Culture="neutral",FileVersion="8.0.50727.42", Type: REG_MULTI_SZ, Length: 404, Data: Du!zKukZ[8DDoq4qr00M>@,s,oxU@??Bf~_96IfEk, gKH-=4wv49{b[v2]HUCqDEXPLORE>@,s,oxU@??Bf~_96IfEk, UvOAm{qpx?)oAC'mF&N`VSTA_IDE>@,s,oxU@??Bf~_96IfEk, ^Sd&qu_%!Ajz=c-67LgzVS_Baseline_Shell>@,s,oxU@??Bf~_96IfEk	HKCR\Installer\Assemblies\Global
20	CultureTest.exe	RegEnumValue	SUCCESS	Index: 4, Name: EnvDTE80,Version="8.0.0.0",PublicKeyToken="b03f5f7f11d50a3a",Culture="neutral",FileVersion="8.0.50727.42", Type: REG_MULTI_SZ, Length: 404, Data: Du!zKukZ[8DDoq4qr00M>t'fLj76Px?g%5Lxn)q8x, gKH-=4wv49{b[v2]HUCqDEXPLORE>t'fLj76Px?g%5Lxn)q8x, UvOAm{qpx?)oAC'mF&N`VSTA_IDE>t'fLj76Px?g%5Lxn)q8x, ^Sd&qu_%!Ajz=c-67LgzVS_Baseline_Shell>t'fLj76Px?g%5Lxn)q8x	HKCR\Installer\Assemblies\Global
21	CultureTest.exe	RegEnumValue	SUCCESS	Index: 5, Name: Microsoft.VisualStudio.Shell,Version="2.0.0.0",PublicKeyToken="b03f5f7f11d50a3a",Culture="neutral",FileVersion="2.0.50727.42",ProcessorArchitecture="MSIL", Type: REG_MULTI_SZ, Length: 386, Data: Du!zKukZ[8DDoq4qr00M>66^Wy*2E=9qqd?H3c$dl, gKH-=4wv49{b[v2]HUCqDEXPLORE>66^Wy*2E=9qqd?H3c$dl, UvOAm{qpx?)oAC'mF&N`VSTA_IDE>66^Wy*2E=9qqd?H3c$dl, UvOAm{qpx?)oAC'mF&N`VSTA_IDE>=f^c@WH_u9~OIp_cDln1	HKCR\Installer\Assemblies\Global
…
1114	CultureTest.exe	RegEnumValue	SUCCESS	Index: 1,098, Name: Policy.11.0.Microsoft.Office.Interop.Word,fileVersion="12.0.4518.1014",version="12.0.0.0000000",culture="neutral",publicKeyToken="71E9BCE111E9429C", Type: REG_MULTI_SZ, Length: 102, Data: w_1^VV!!!!!!!!!MKKSkWord_PIA>$c5^P,b`F=p4x$@{SnSa	HKCR\Installer\Assemblies\Global
1115	CultureTest.exe	RegEnumValue	SUCCESS	Index: 1,099, Name: Microsoft.Vbe.Interop,Version="11.0.0.0000",Culture="neutral",PublicKeyToken="71e9bce111e9429c",FileVersion="11.0.8161.0", Type: REG_MULTI_SZ, Length: 120, Data: (f'^Vn-}f(ZXfeAR6.jiVSCommonPIAHidden>X.2kG@=8r=omnVtBlW4t	HKCR\Installer\Assemblies\Global
1116	CultureTest.exe	RegEnumValue	NO MORE ENTRIES	Index: 1,100, Length: 4,168	HKCR\Installer\Assemblies\Global

Mivel nem akarok senkivel kitolni kivágtam ezer sort a kimenetből. Ráadásul az előbb 2x is lefut a registryben. Mi a fene ez?
A .NET betöltője (fusion) ha nem tud betölteni egy assembly-t a probing folyamat során, akkor végső kétségbeesésében arra gondol, biztos ott van az, csak letörölték. Elő hát az MSI installerrel -ha van neki- és állítsuk vissza azt telepítésből - gondolja, és így is tesz. Átnézi a fenti több mint ezer bejegyzést, hátha. De nem. Sajnos ezen hiábavaló próbálkozás elég sok időt elvisz, akár 1-2 mp-cel is lassabbá teheti a program elindulását.
Számomra ez egy igen bosszantó, okoskodó fícsör, írtam is Junfeng Zhang-nak, ki lehet-e kapcsolni, de sajnos nem kaptam választ.
Mi mégis a megoldás? Meg kell akadályozni a keresgélést, ha nincs szükségünk erre a szolgáltatásra.
Tegyük fel nem szeretném lokalizálni az appot egyelőre, azaz számomra teljesen felesleges ez a keresgélés. Hogyan lehet megmondani, hogy az erőforrásokat csak a fő assemblyben keresse?
Egyszerű, a Main() elejére:


Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture;

Ezek után már egyáltalán nem keresgél a lemezen és a registryben sem. Semennyire. Egyszerű? Tetszik? :)

2 Responses to “.NET teljesítményhangolási tapasztalatok 1.”

  1. KRis Says:

    Hello,

    Ez nem ehhez kapcsolódik?!?
    ——-

    http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-in-the-bcl-in-net-4-0-justin-van-patten.aspx

    ResourceManager Improvements
    The ResourceManager in System.Resources has been improved to respect the user’s preferred UI languages when looking for localized resources, instead of only using the CurrentUICulture’s parent chain. This means if the user has specified that she prefers French and Spanish, the ResourceManager will look for French and Spanish resources before falling back to the neutral resources. This change is present in Silverlight 2 as well as .NET 4.0.

  2. Soczó Zsolt Says:

    De, köszi a pointert.

Leave a Reply