<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blog.vyvojar.cz/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Bobrisuv blog</title><link>http://blog.vyvojar.cz/bobris/default.aspx</link><description>O .Netu, C#, F#, C++, Embeded databázích, prostě o všem o čem budu mít chuť psát.</description><dc:language /><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Zjednodušení DynamicMethod</title><link>http://blog.vyvojar.cz/bobris/archive/2011/10/06/zjednodu-en-dynamicmethod.aspx</link><pubDate>Thu, 06 Oct 2011 21:35:35 GMT</pubDate><guid isPermaLink="false">99a92ff2-698a-48c2-8eaf-f3d9b6202627:239433</guid><dc:creator>bobris</dc:creator><slash:comments>0</slash:comments><comments>http://blog.vyvojar.cz/bobris/comments/239433.aspx</comments><wfw:commentRss>http://blog.vyvojar.cz/bobris/commentrss.aspx?PostID=239433</wfw:commentRss><wfw:comment>http://blog.vyvojar.cz/bobris/rsscomments.aspx?PostID=239433</wfw:comment><description>&lt;p&gt;Možná si ještě vzpomínáte jak jsem tu &lt;a href="http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx" target="_blank"&gt;nedávno&lt;/a&gt; ukazoval zjednodušení pro generování IL kódu za běhu programu. No a když začnete generovat velké množství IL kódu, tak se asi chybám nevyhnete. Když generujete celou assembly, tak ji není problém uložit a podívat se na ní reflektorem(nebo ILSpy a spoustou jiných klonů), či zkontrolovat pomocí PEVerify. No jo ale co když používáte pouze DynamicMethod? Určitě se hodí &lt;a href="http://osherove.com/blog/2007/11/29/il-debug-visualizer-for-compiled-lambda-expressions-methodba.html" target="_blank"&gt;tento&lt;/a&gt; Debugger Vizualizer. Ale problém se pěkně vyřeší až tímto obalem:&lt;/p&gt; &lt;p&gt;Nejdříve odkazy na zdroják:&lt;/p&gt; &lt;p&gt;&lt;a href="https://github.com/Bobris/BTDB/blob/unstable/BTDB/IL/DynamicMethod.cs"&gt;https://github.com/Bobris/BTDB/blob/unstable/BTDB/IL/DynamicMethod.cs&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Po staru bylo nutné napsat toto:&lt;/p&gt;&lt;pre&gt;var method = new DynamicMethod("SampleCall", typeof(Nested), Type.EmptyTypes);&lt;br&gt;…&lt;br&gt;&lt;font face="Courier New"&gt;var action = (Func&amp;lt;Nested&amp;gt;)method.CreateDelegate(typeof(Func&amp;lt;Nested&amp;gt;));&lt;/font&gt;&lt;/pre&gt;
&lt;p&gt;Jak vidíte kód obsahuje velké množství duplicitní informace. Pomocí právě představené generické obálky už jen takto krátce:&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;var method = new DynamicMethod&amp;lt;Func&amp;lt;Nested&amp;gt;&amp;gt;("SampleCall");&lt;br&gt;…&lt;br&gt;var action = method.Create();&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Ale hlavní výhoda je, že implementaci obálky můžeme na jednom místě změnit a tak místo generování pouze kódu v paměti, vytvořit i dll, kterou můžeme lehce zkontrolovat a tak rychleji odstranit chyby.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Na závěr malý hartusení(rant). Metro Win8 .Net aplikace zatím podporují právě pouze DynamicMethod (což byla novinka .Net 2.0), i Silverlight 4 podporuje podstatně rozsáhlejší DynamicAssembly, jak si MS vůbec může dovolit takovéto regrese ve funkcionalitě je pro mne záhadou. Bohužel při tolik opěvovaném jarním úklidu .Netu omylem rozbili i pár čínských váz. Portable Library project pak neobsahuje ani tuto DynamicMethod, ale oni šli ještě dál, protože tam nejsou ani Collections.Concurrent a ani Task&amp;lt;T&amp;gt;, takže to je snad vhodný jen na DTO objekty… Ale chápu, že vynoření z téhle bažiny nekompatibilit, kterou si ovšem naprosto zbytečně zavařili sami, něco dá a jsem rád, alespoň za tuto snahu.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Přidej do&lt;/strong&gt; &lt;a href = "http://linkuj.cz/?id=linkuj&amp;amp;url=http://blog.vyvojar.cz/bobris/archive/2011/10/06/zjednodu-en-dynamicmethod.aspx&amp;amp;;title=Zjednodu%c5%a1en%26%23237%3b+DynamicMethod" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/10/06/zjednodu-en-dynamicmethod.aspx"&gt;linkuj.cz!&lt;/a&gt; |  &lt;a href = "http://www.jagg.cz/bookmarks.php?action=add&amp;amp;address=http://blog.vyvojar.cz/bobris/archive/2011/10/06/zjednodu-en-dynamicmethod.aspx&amp;amp;;title=Zjednodu%c5%a1en%26%23237%3b+DynamicMethod" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/10/06/zjednodu-en-dynamicmethod.aspx"&gt;jagg.cz!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://blog.vyvojar.cz/bobris/archive/2011/10/06/zjednodu-en-dynamicmethod.aspx&amp;amp;;title=Zjednodu%c5%a1en%26%23237%3b+DynamicMethod" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/10/06/zjednodu-en-dynamicmethod.aspx"&gt;del.icio.us!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2011/10/06/zjednodu-en-dynamicmethod.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/10/06/zjednodu-en-dynamicmethod.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2011/10/06/zjednodu-en-dynamicmethod.aspx&amp;amp;title=Zjednodu%c5%a1en%26%23237%3b+DynamicMethod" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/10/06/zjednodu-en-dynamicmethod.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://blog.vyvojar.cz/bobris/archive/2011/10/06/zjednodu-en-dynamicmethod.aspx&amp;amp;;title=Zjednodu%c5%a1en%26%23237%3b+DynamicMethod" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/10/06/zjednodu-en-dynamicmethod.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://blog.vyvojar.cz/bobris/archive/2011/10/06/zjednodu-en-dynamicmethod.aspx&amp;amp;;title=Zjednodu%c5%a1en%26%23237%3b+DynamicMethod&amp;amp;;top=1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/10/06/zjednodu-en-dynamicmethod.aspx"&gt;live it!&lt;/a&gt; |  &lt;a href = "mailto:?body=Thought you might like this: http://blog.vyvojar.cz/bobris/archive/2011/10/06/zjednodu-en-dynamicmethod.aspx&amp;amp;;subject=Zjednodu%c5%a1en%26%23237%3b+DynamicMethod" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/10/06/zjednodu-en-dynamicmethod.aspx"&gt;email it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blog.vyvojar.cz/aggbug.aspx?PostID=239433" width="1" height="1"&gt;</description><category domain="http://blog.vyvojar.cz/bobris/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Opravdu nema .Net budoucnost?</title><link>http://blog.vyvojar.cz/bobris/archive/2011/09/29/opravdu-nema-net-budoucnost.aspx</link><pubDate>Wed, 28 Sep 2011 22:41:07 GMT</pubDate><guid isPermaLink="false">99a92ff2-698a-48c2-8eaf-f3d9b6202627:239261</guid><dc:creator>bobris</dc:creator><slash:comments>10</slash:comments><comments>http://blog.vyvojar.cz/bobris/comments/239261.aspx</comments><wfw:commentRss>http://blog.vyvojar.cz/bobris/commentrss.aspx?PostID=239261</wfw:commentRss><wfw:comment>http://blog.vyvojar.cz/bobris/rsscomments.aspx?PostID=239261</wfw:comment><description>&lt;p&gt;Nejdrive jsem to psal jako komentar k &lt;a title="http://blog.vyvojar.cz/michalowo/archive/2011/09/27/vc-11-aneb-postupn-konec-netu.aspx" href="http://blog.vyvojar.cz/michalowo/archive/2011/09/27/vc-11-aneb-postupn-konec-netu.aspx"&gt;http://blog.vyvojar.cz/michalowo/archive/2011/09/27/vc-11-aneb-postupn-konec-netu.aspx&lt;/a&gt;, ale uz to bylo moc dlouhy tak to hodim do blogu, navic jsem stejne k tematu chtel neco napsat.&lt;/p&gt; &lt;p&gt;Myslim, ze to Michal nemyslel vazne, a chtel si jen zadiskutovat, ci zjistit pocity komunity k tematu, tak tedy do toho…&lt;/p&gt; &lt;p&gt;Nejdrive k “WinC++” se jiz vzilo oznaceni C++/CX. Pro ty co to jeste nevedi tak to je nastavba C++, syntaxi temer identicka k C++/CLI, ale s uplne jinym nativnim kod generatorem.&lt;/p&gt; &lt;p&gt;Souhlasim, ze WinRT je hodne o vyhre Windows divize(dale jen WinDiv) a mit neco rychle aby iPad nemel naskok 3 roky. Ale DevDiv pouzila trojskeho kone jmenem Async. Ano tim ze udelali vsechno async a C++ na rozdil od C#/VB pro to nema podporu, tak se v tom neda programovat nic slozitejsiho a uz vubec se to neda cist. Dodelat podporu pro Async do jazyka tak sloziteho jako je C++ a navic bez GC (jak vyresit closure?), je prakticky nemozny. Dnes je opravdu hodne modni mluvit o renezanci C++, ale v realu to neni zadna sranda, rychlosti kompilace a linkovani jsou stale k placi.&lt;/p&gt; &lt;p&gt;WinRT je stale "common runtime" (ve vyznamu ze musi byt pouzitelne z vice jazyku/platforem) a uz pomalu vyliza na svetlo jak pomaly to je (Jasne ze v dobe JS v mainstreamu uz na rychlost nikdo nehraje). Vetsina lidi totiz neumi Assembler (a priznam se ze ani me to netrklo i kdyz se mi to zdalo divny), tak si te lzi na Buildu jako ze v C++ to je jen prime volani metody nevsimla, detaily zde &lt;a href="http://www.interact-sw.co.uk/iangblog/"&gt;http://www.interact-sw.co.uk/iangblog/&lt;/a&gt; (pokud to nechcete cist cely tak hledejte “That’s Not a Vtbl—THIS is a Vtbl”). Samozrejme ted uz se tahle lez vsude opakuje, dulezity je marketing, ne realita, a v “Hello world” aplikacich na tom fakt nezalezi, a jiny se na tablety delat nebudou.&lt;/p&gt; &lt;p&gt;V komentarich se strhla diskuze o GC k tomu muj pohled: GC je samozrejme vyrazne rychlejsi nez atomicky reference counting (I v MS to vedi minimalne 11 let viz &lt;a href="http://blogs.msdn.com/b/brada/archive/2005/02/11/371015.aspx"&gt;http://blogs.msdn.com/b/brada/archive/2005/02/11/371015.aspx&lt;/a&gt;). Vyhoda C++ je v tom, ze kdyz si date hodne prace s optimalizacemi (manualnimi), tak se muzete vyhnout tomu reference countingu a tak byt vetsinou rychlejsi, stale ovsem zustava problem s fragmentaci pameti (V Metro aplikacich ume “vyreseno” nepodporou behu aplikaci na pozadi :-). Navic casto navrhovane rozdeleni aplikace na UI v C# (nedej boze v JS) a zbytek v C++, tak ma prave problem s navrhem rozhrani (ve smyslu interface) – jakekoliv volani na rozhrani (ve smyslu boundary :-) bude mit klasicky vykonostni propad jako v pripade PInvoke, takze to co mozna ziskate v C++ tak hned ztratite…&lt;/p&gt; &lt;p&gt;K MS, a jejich strategii. Tim ze i z MS zazniva odklon od .Netu, tak si predcasne podkopavaji WP7(.5). Protoze jestlize WP8 budou postavene nad WinRT, tak se budou muset vsechny aplikace napsat znovu, a tim vyvojare k WP7.5 neprilakaji.&lt;/p&gt; &lt;p&gt;Jinak asi dost hodne .Net vyvojaru v MS uteklo do &lt;a href="http://en.wikipedia.org/wiki/Midori_(operating_system"&gt;Midori&lt;/a&gt;, i kdyz nevim jestli tam zustanou pred WinDiv v bezpeci.&lt;/p&gt; &lt;p&gt;Zpet k .Netu:&lt;/p&gt; &lt;p&gt;.Net a obecne managed prostredi maji vyhodu v JITu, Reflexi a GC. Umoznujici vytvaret skriptovatelne aplikace bez impaktu na rychlost. Znovu jako za starych casu vytvaret samomodifikujici se kod pro maximalni rychlost. A to vse +- nezavisle na platforme. .Net i JVM maji stale moznosti jak se vylepsovat, nativni kod se bude uz jen zpomalovat :-) a to vubec nemluvim o produktivite programatoru.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Dockame se renezance .Netu? Protoze pokud ne, tak nebudem psat v C++, ale v ObjectiveC… (A na to jsem asi fakt uz starej)&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Přidej do&lt;/strong&gt; &lt;a href = "http://linkuj.cz/?id=linkuj&amp;amp;url=http://blog.vyvojar.cz/bobris/archive/2011/09/29/opravdu-nema-net-budoucnost.aspx&amp;amp;;title=Opravdu+nema+.Net+budoucnost%3f" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/09/29/opravdu-nema-net-budoucnost.aspx"&gt;linkuj.cz!&lt;/a&gt; |  &lt;a href = "http://www.jagg.cz/bookmarks.php?action=add&amp;amp;address=http://blog.vyvojar.cz/bobris/archive/2011/09/29/opravdu-nema-net-budoucnost.aspx&amp;amp;;title=Opravdu+nema+.Net+budoucnost%3f" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/09/29/opravdu-nema-net-budoucnost.aspx"&gt;jagg.cz!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://blog.vyvojar.cz/bobris/archive/2011/09/29/opravdu-nema-net-budoucnost.aspx&amp;amp;;title=Opravdu+nema+.Net+budoucnost%3f" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/09/29/opravdu-nema-net-budoucnost.aspx"&gt;del.icio.us!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2011/09/29/opravdu-nema-net-budoucnost.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/09/29/opravdu-nema-net-budoucnost.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2011/09/29/opravdu-nema-net-budoucnost.aspx&amp;amp;title=Opravdu+nema+.Net+budoucnost%3f" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/09/29/opravdu-nema-net-budoucnost.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://blog.vyvojar.cz/bobris/archive/2011/09/29/opravdu-nema-net-budoucnost.aspx&amp;amp;;title=Opravdu+nema+.Net+budoucnost%3f" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/09/29/opravdu-nema-net-budoucnost.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://blog.vyvojar.cz/bobris/archive/2011/09/29/opravdu-nema-net-budoucnost.aspx&amp;amp;;title=Opravdu+nema+.Net+budoucnost%3f&amp;amp;;top=1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/09/29/opravdu-nema-net-budoucnost.aspx"&gt;live it!&lt;/a&gt; |  &lt;a href = "mailto:?body=Thought you might like this: http://blog.vyvojar.cz/bobris/archive/2011/09/29/opravdu-nema-net-budoucnost.aspx&amp;amp;;subject=Opravdu+nema+.Net+budoucnost%3f" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/09/29/opravdu-nema-net-budoucnost.aspx"&gt;email it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blog.vyvojar.cz/aggbug.aspx?PostID=239261" width="1" height="1"&gt;</description><category domain="http://blog.vyvojar.cz/bobris/archive/tags/Async/default.aspx">Async</category><category domain="http://blog.vyvojar.cz/bobris/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blog.vyvojar.cz/bobris/archive/tags/C_2B002B00_/default.aspx">C++</category></item><item><title>BDB vs BTDB</title><link>http://blog.vyvojar.cz/bobris/archive/2011/06/14/bdb-vs-btdb.aspx</link><pubDate>Mon, 13 Jun 2011 22:00:00 GMT</pubDate><guid isPermaLink="false">99a92ff2-698a-48c2-8eaf-f3d9b6202627:238445</guid><dc:creator>bobris</dc:creator><slash:comments>0</slash:comments><comments>http://blog.vyvojar.cz/bobris/comments/238445.aspx</comments><wfw:commentRss>http://blog.vyvojar.cz/bobris/commentrss.aspx?PostID=238445</wfw:commentRss><wfw:comment>http://blog.vyvojar.cz/bobris/rsscomments.aspx?PostID=238445</wfw:comment><description>&lt;p&gt;Můj projekt &lt;a href="https://github.com/Bobris/BTDB"&gt;BTDB&lt;/a&gt; je již tak daleko, že snese i nějaký to rychlostní porovnání. Nejdříve porovnám nejnižší úroveň databáze klíč hodnota, klíče jsou setříděné a je tedy možné jimi iterovat.&lt;/p&gt;
 
&lt;p&gt;Asi nejznámější “konkurence” je &lt;a href="http://www.oracle.com/technetwork/database/berkeleydb/overview/index.html"&gt;Berkeley DB&lt;/a&gt; (BDB), aktuálně patřící Oraclu. Pro test jsem použil Berkeley DB 11g Release 2, library version 11.2.5.1.25: (January 28, 2011) tedy aktuální verzi v době psaní toho článku. Je pěkné, že má i .Net knihovnu, která je pouze zaobalením Céčkové implementace. Což znamená, že v případě povolení pouze bezpečného .Net kódu máte smůlu (třeba SL, WP7).&lt;/p&gt;
 
&lt;p&gt;BDB má řekl bych až šíleně mnoho nastavení. Pokusil jsem se ji nastavit co nejblíže implementaci BTDB. ACID transakce se serializovatelnými transakcemi pomocí MVCC. Bohužel nejsem na BDB odborník, takže velmi rád přivítám radu jak ji nastavit lépe (se zachováním těchto vlastností). Především jsem nepřišel na to jak vypnout transakční log aby byla zachována durabilita (ale i v dokumentaci mají napsáno, že by to jít nemělo). Taky jsem zapnul kontrolu kontrolního součtu při čtení stránek z disku (BDB používá o něco méně kvalitní funkci než Flatcher32 použitá v BTDB, ale i tak to je velmi podobné). Vše jsem ověřoval v Profileru, kde nebyly vidět žádné zbytečné funkce.&lt;/p&gt;
 
&lt;p&gt;Pro samotný test jsem zvolil 200 transakcí, kde každá vytvoří 200 párů 2 bytového klíče a různě dlouhých hodnot. Tato první část ukazuje rychlost vytvoření databáze pokud začneme z nuly.&lt;/p&gt;
 
&lt;p&gt;Druhá část je i se čtením který přečte všechny klíče a hodnoty v každé transakci před commit a tím otestuje správnou implementaci serializace transakcí. V podstatě to je téměř hlavně na čtení zaměřený test. Pro čistý čas čtení lze jen odečíst čas prvního testu. &lt;/p&gt;
 
&lt;p&gt;Třetí test je stejný jako první s rozdílem, že databázi nechám naplněnou z druhého testu. Tento test tedy testuje rychlost zapisování nových hodnot do existujících párů klíč hodnota.&lt;/p&gt;
 
&lt;p&gt;Pro detaily se podívejte do implementací testu:&lt;/p&gt;
 
&lt;p&gt;v BTDB: &lt;a href="https://gist.github.com/1023790"&gt;https://gist.github.com/1023790&lt;/a&gt;&lt;/p&gt;
 
&lt;p&gt;v BDB: &lt;a href="https://gist.github.com/1023779"&gt;https://gist.github.com/1023779&lt;/a&gt;&lt;/p&gt;
  
&lt;p&gt;Ve všech případech se pro kontrolu vypsal tento řádek:&lt;/p&gt;
 
&lt;p&gt;&lt;font face="Courier New"&gt;Pure data length: 396130000&lt;/font&gt;&lt;/p&gt;
 
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt;
 
&lt;p&gt;Naměřené výsledky podrobně:&lt;/p&gt;
 
&lt;p&gt;Pouze vytvoření BTDB:&lt;/p&gt;
 
&lt;p&gt;&lt;font face="Courier New"&gt;KeyValuePairCount:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 40000&lt;br&gt;TransactionNumber:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 201&lt;br&gt;WastedSize:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 773120&lt;br&gt;ReallyUsedSize:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 411252224&lt;br&gt;DatabaseStreamSize:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 412025344&lt;br&gt;Total Bytes Read:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&lt;br&gt;Total Bytes Written:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 547714176&lt;br&gt;Time:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;4170,065ms&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
 
&lt;p&gt;Pouze vytvoření BDB:&lt;/p&gt;
 
&lt;p&gt;&lt;font face="Courier New"&gt;Time: &lt;strong&gt;58325ms&lt;/strong&gt;&lt;br&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;DB Size: 534675456&lt;br&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;Log Size: 20971520&lt;/font&gt;&lt;/p&gt;
 
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt;
 
&lt;p&gt;Vytvoření a čtení BTDB:&lt;/p&gt;
 
&lt;p&gt;&lt;font face="Courier New"&gt;KeyValuePairCount:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 40000&lt;br&gt;TransactionNumber:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 201&lt;br&gt;WastedSize:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 773120&lt;br&gt;ReallyUsedSize:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 411252224&lt;br&gt;DatabaseStreamSize:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 412025344&lt;br&gt;Total Bytes Read:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 26527795200&lt;br&gt;Total Bytes Written:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 547714176&lt;br&gt;Time:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;133180,8132ms&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
 
&lt;p&gt;Vytvoření a čtení BDB:&lt;/p&gt;
 
&lt;p&gt;&lt;font face="Courier New"&gt;Time: &lt;strong&gt;212204ms&lt;br&gt;&lt;/strong&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;DB Size: 534675456&lt;br&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;Log Size: 20971520&lt;/font&gt;&lt;/p&gt;
  
&lt;p&gt;Třetí přepisovací část v BTDB:&lt;/p&gt;
 
&lt;p&gt;&lt;font face="Courier New"&gt;KeyValuePairCount:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 40000&lt;br&gt;TransactionNumber:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 400&lt;br&gt;WastedSize:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1477120&lt;br&gt;ReallyUsedSize:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 411252224&lt;br&gt;DatabaseStreamSize:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 412729344&lt;br&gt;Total Bytes Read:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 407810048&lt;br&gt;Total Bytes Written:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 541159552&lt;br&gt;Time:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;5863,4538ms&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
 
&lt;p&gt;Třetí přepisovací část v BDB:&lt;/p&gt;
 
&lt;p&gt;&lt;font face="Courier New"&gt;Time: &lt;strong&gt;64572ms&lt;br&gt;&lt;/strong&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;DB Size: 534675456&lt;br&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;Log Size: 20971520&lt;/font&gt;&lt;/p&gt;
  
&lt;p&gt;Takže si to sepíšeme do tabulky (stále jsem napřišel na to jak na tomhle blogu udělat v tabulce rámečky :-O):&lt;/p&gt;
 
&lt;table cellSpacing="1" cellPadding="2"&gt;


&lt;tr&gt; 
&lt;td&gt;&amp;nbsp;&lt;/td&gt;

&lt;td&gt;Fáze 1&lt;/td&gt;
 
&lt;td&gt;Fáze 2-1&lt;/td&gt;
 
&lt;td&gt;Fáze 3&lt;/td&gt;
 
&lt;td&gt;DB Size/data&lt;/td&gt;
&lt;/tr&gt;
 
&lt;tr&gt; 
&lt;td&gt;BTDB&lt;/td&gt;
 
&lt;td&gt;4s&lt;/td&gt;
 
&lt;td&gt;129s&lt;/td&gt;
 
&lt;td&gt;6s&lt;/td&gt;
 
&lt;td&gt;104% &lt;/td&gt;
&lt;/tr&gt;
 
&lt;tr&gt; 
&lt;td&gt;BDB&lt;/td&gt;
 
&lt;td&gt;58s&lt;/td&gt;
 
&lt;td&gt;154s&lt;/td&gt;
 
&lt;td&gt;65s&lt;/td&gt;
 
&lt;td&gt;135%&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
 
&lt;p&gt;No na čistě .Net implementaci to je hodně slušný. Z mého zaujatého pohledu vidím tyto výhody obou řešení:&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;BTDB&lt;/strong&gt;&lt;/p&gt;
 
&lt;li&gt;pouze Managed .Net&lt;/li&gt;
 
&lt;li&gt;malá (150kb)&lt;/li&gt;
 
&lt;li&gt;jednoduše použitelná díky málo funkcím a přirozenému .Net rozhraní&lt;/li&gt;
 
&lt;li&gt;DB potřebuje jen o malo více diskové kapacity než samotná data&lt;/li&gt;
 
&lt;li&gt;rychlá (hlavně v 64bit .Netu)&lt;/li&gt;
 
&lt;li&gt;bez divných limitů (např. neomezená velikost transakce)&lt;/li&gt;
 
&lt;p&gt;&lt;strong&gt;BDB&lt;/strong&gt;&lt;/p&gt;
 
&lt;li&gt;použitelná z více jazyků&lt;/li&gt;
 
&lt;li&gt;mraky funkcí&lt;/li&gt;
 
&lt;li&gt;ověřená časem&lt;/li&gt;
 
&lt;li&gt;více paralelních zapisujících transakcí&lt;/li&gt;
 
&lt;li&gt;dokáže běžet i v módech kdy více procesu sdílí stejnou databázi&lt;/li&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Přidej do&lt;/strong&gt; &lt;a href = "http://linkuj.cz/?id=linkuj&amp;amp;url=http://blog.vyvojar.cz/bobris/archive/2011/06/14/bdb-vs-btdb.aspx&amp;amp;;title=BDB+vs+BTDB" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/06/14/bdb-vs-btdb.aspx"&gt;linkuj.cz!&lt;/a&gt; |  &lt;a href = "http://www.jagg.cz/bookmarks.php?action=add&amp;amp;address=http://blog.vyvojar.cz/bobris/archive/2011/06/14/bdb-vs-btdb.aspx&amp;amp;;title=BDB+vs+BTDB" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/06/14/bdb-vs-btdb.aspx"&gt;jagg.cz!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://blog.vyvojar.cz/bobris/archive/2011/06/14/bdb-vs-btdb.aspx&amp;amp;;title=BDB+vs+BTDB" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/06/14/bdb-vs-btdb.aspx"&gt;del.icio.us!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2011/06/14/bdb-vs-btdb.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/06/14/bdb-vs-btdb.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2011/06/14/bdb-vs-btdb.aspx&amp;amp;title=BDB+vs+BTDB" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/06/14/bdb-vs-btdb.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://blog.vyvojar.cz/bobris/archive/2011/06/14/bdb-vs-btdb.aspx&amp;amp;;title=BDB+vs+BTDB" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/06/14/bdb-vs-btdb.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://blog.vyvojar.cz/bobris/archive/2011/06/14/bdb-vs-btdb.aspx&amp;amp;;title=BDB+vs+BTDB&amp;amp;;top=1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/06/14/bdb-vs-btdb.aspx"&gt;live it!&lt;/a&gt; |  &lt;a href = "mailto:?body=Thought you might like this: http://blog.vyvojar.cz/bobris/archive/2011/06/14/bdb-vs-btdb.aspx&amp;amp;;subject=BDB+vs+BTDB" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/06/14/bdb-vs-btdb.aspx"&gt;email it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blog.vyvojar.cz/aggbug.aspx?PostID=238445" width="1" height="1"&gt;</description><category domain="http://blog.vyvojar.cz/bobris/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blog.vyvojar.cz/bobris/archive/tags/DB/default.aspx">DB</category></item><item><title>Fluent Reflection.Emit</title><link>http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx</link><pubDate>Wed, 25 May 2011 22:11:27 GMT</pubDate><guid isPermaLink="false">99a92ff2-698a-48c2-8eaf-f3d9b6202627:238180</guid><dc:creator>bobris</dc:creator><slash:comments>6</slash:comments><comments>http://blog.vyvojar.cz/bobris/comments/238180.aspx</comments><wfw:commentRss>http://blog.vyvojar.cz/bobris/commentrss.aspx?PostID=238180</wfw:commentRss><wfw:comment>http://blog.vyvojar.cz/bobris/rsscomments.aspx?PostID=238180</wfw:comment><description>&lt;p&gt;Dnes se dovíte jak udělat váš IL generující kód čitelnější a navíc přívětivý k refaktoringu.&lt;/p&gt; &lt;p&gt;Mějme tento jednoduchý test:&lt;/p&gt; &lt;div id="codeSnippetWrapper"&gt;&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Nested&lt;br&gt;{&lt;br&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; PassedParam { get; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; set; }&lt;br&gt;&lt;br&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Fun(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; a)&lt;br&gt;    {&lt;br&gt;        PassedParam = a;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Fun(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; noFun)&lt;br&gt;    {&lt;br&gt;        Assert.Fail();&lt;br&gt;    }&lt;br&gt;}&lt;br&gt;&lt;br&gt;[Test]&lt;br&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; NoILWay()&lt;br&gt;{&lt;br&gt;    var n = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Nested();&lt;br&gt;    n.Fun(&lt;span style="color:#006080;"&gt;"Test"&lt;/span&gt;);&lt;br&gt;    Assert.AreEqual(&lt;span style="color:#006080;"&gt;"Test"&lt;/span&gt;, n.PassedParam);&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;
&lt;p&gt;Zkusme ho tedy přepsat do DynamicMethod jen s tím co je .Net 4.0:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;[Test]&lt;br&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; ILOldWay()&lt;br&gt;{&lt;br&gt;    var method = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DynamicMethod(&lt;span style="color:#006080;"&gt;"SampleCall"&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(Nested), Type.EmptyTypes);&lt;br&gt;    var il = method.GetILGenerator();&lt;br&gt;    il.DeclareLocal(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(Nested));&lt;br&gt;    il.Emit(OpCodes.Newobj, &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(Nested).GetConstructor(Type.EmptyTypes));&lt;br&gt;    il.Emit(OpCodes.Stloc_0);&lt;br&gt;    il.Emit(OpCodes.Ldloc_0);&lt;br&gt;    il.Emit(OpCodes.Ldstr, &lt;span style="color:#006080;"&gt;"Test"&lt;/span&gt;);&lt;br&gt;    il.Emit(OpCodes.Call, &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(Nested).GetMethod(&lt;span style="color:#006080;"&gt;"Fun"&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt;[] { &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;) }));&lt;br&gt;    il.Emit(OpCodes.Ldloc_0);&lt;br&gt;    il.Emit(OpCodes.Ret);&lt;br&gt;    var action = (Func&amp;lt;Nested&amp;gt;)method.CreateDelegate(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(Func&amp;lt;Nested&amp;gt;));&lt;br&gt;    var n = action();&lt;br&gt;    Assert.AreEqual(&lt;span style="color:#006080;"&gt;"Test"&lt;/span&gt;, n.PassedParam);&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;

&lt;p&gt;Především si všimněte řádků s Newobj a Call instrukcemi. Co by se totiž stalo kdyby jsme třeba zrušili konstruktor s nula parametry, nebo přejmenovali funkci Fun, problém bychom nalezli až za běhu. Takže co využít Expression a extension metody. Fluent interface FTW.&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; ILGenerator Newobj(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; ILGenerator il, Expression&amp;lt;Action&amp;gt; expression)&lt;br&gt;{&lt;br&gt;    var constructorInfo = (expression.Body &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; NewExpression).Constructor;&lt;br&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; Newobj(il, constructorInfo);&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; ILGenerator Newobj(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; ILGenerator il, ConstructorInfo constructorInfo)&lt;br&gt;{&lt;br&gt;    il.Emit(OpCodes.Newobj, constructorInfo);&lt;br&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; il;&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;

&lt;p&gt;Protože C# nemá možnost přímo zakódovat token k metodě, přesto tato funkce je použitá pro vytvoření Expression. Pak už si ho ve funkci zjistíme a zbytek Expression zahodíme protože nás nezajímá. Samotný ILGenerator jen vrátíme pro umožnění velmi kompaktního zápisu.&lt;/p&gt;
&lt;p&gt;Takže po o něco víc podobných metodách lze stejný kód zapsat takto:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;[Test]&lt;br&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; ILNewWay()&lt;br&gt;{&lt;br&gt;    var method = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DynamicMethod(&lt;span style="color:#006080;"&gt;"SampleCall"&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(Nested), Type.EmptyTypes);&lt;br&gt;    var il = method.GetILGenerator();&lt;br&gt;    il.DeclareLocal(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(Nested));&lt;br&gt;    il&lt;br&gt;        .Newobj(() =&amp;gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Nested())&lt;br&gt;        .Stloc(0)&lt;br&gt;        .Ldloc(0)&lt;br&gt;        .Ldstr(&lt;span style="color:#006080;"&gt;"Test"&lt;/span&gt;)&lt;br&gt;        .Call(() =&amp;gt; ((Nested)&lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;).Fun(&lt;span style="color:#006080;"&gt;""&lt;/span&gt;))&lt;br&gt;        .Ldloc(0)&lt;br&gt;        .Ret();&lt;br&gt;    var action = method.CreateDelegate&amp;lt;Func&amp;lt;Nested&amp;gt;&amp;gt;();&lt;br&gt;    var n = action();&lt;br&gt;    Assert.AreEqual(&lt;span style="color:#006080;"&gt;"Test"&lt;/span&gt;, n.PassedParam);&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;
&lt;p&gt;Kompletní kód aktuálně najdete (vše v MIT Licenci):&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/Bobris/BTDB/tree/unstable/BTDB/IL"&gt;https://github.com/Bobris/BTDB/tree/unstable/BTDB/IL&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/Bobris/BTDB/blob/unstable/BTDBTest/ILExtensionsTest.cs"&gt;https://github.com/Bobris/BTDB/blob/unstable/BTDBTest/ILExtensionsTest.cs&lt;/a&gt;&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Přidej do&lt;/strong&gt; &lt;a href = "http://linkuj.cz/?id=linkuj&amp;amp;url=http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx&amp;amp;;title=Fluent+Reflection.Emit" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx"&gt;linkuj.cz!&lt;/a&gt; |  &lt;a href = "http://www.jagg.cz/bookmarks.php?action=add&amp;amp;address=http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx&amp;amp;;title=Fluent+Reflection.Emit" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx"&gt;jagg.cz!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx&amp;amp;;title=Fluent+Reflection.Emit" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx"&gt;del.icio.us!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx&amp;amp;title=Fluent+Reflection.Emit" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx&amp;amp;;title=Fluent+Reflection.Emit" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx&amp;amp;;title=Fluent+Reflection.Emit&amp;amp;;top=1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx"&gt;live it!&lt;/a&gt; |  &lt;a href = "mailto:?body=Thought you might like this: http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx&amp;amp;;subject=Fluent+Reflection.Emit" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/05/26/fluent-reflection-emit.aspx"&gt;email it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blog.vyvojar.cz/aggbug.aspx?PostID=238180" width="1" height="1"&gt;</description><category domain="http://blog.vyvojar.cz/bobris/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Záludnost v ILGenerator.Emit</title><link>http://blog.vyvojar.cz/bobris/archive/2011/05/20/zaludnost-v-ilgenerator-emit.aspx</link><pubDate>Fri, 20 May 2011 21:50:00 GMT</pubDate><guid isPermaLink="false">99a92ff2-698a-48c2-8eaf-f3d9b6202627:238172</guid><dc:creator>bobris</dc:creator><slash:comments>0</slash:comments><comments>http://blog.vyvojar.cz/bobris/comments/238172.aspx</comments><wfw:commentRss>http://blog.vyvojar.cz/bobris/commentrss.aspx?PostID=238172</wfw:commentRss><wfw:comment>http://blog.vyvojar.cz/bobris/rsscomments.aspx?PostID=238172</wfw:comment><description>&lt;p&gt;Pokud chcete napsat něco netriviálního s použitím dynamicky generovaného kódu v .Netu, tak si začnete vytvářet různé pomocné funkce.&lt;/p&gt;  &lt;p&gt;Jako například funkci na načtení int konstanty na zásobník (zkráceno):&lt;/p&gt;  &lt;pre class="csharpcode"&gt;OpCode op = &lt;span class="kwrd"&gt;value&lt;/span&gt; &amp;gt;= -128 &amp;amp;&amp;amp; &lt;span class="kwrd"&gt;value&lt;/span&gt; &amp;lt;= 127 ? OpCodes.Ldc_I4_S : OpCodes.Ldc_I4;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;il.Emit(op, &lt;span class="kwrd"&gt;value&lt;/span&gt;);&lt;/pre&gt;&lt;p&gt;Říkáte si jak ste dobrý, když stejný kód napíšou i takové špičky jako Marc Gravell. No ale je to blbě.&lt;/p&gt;&lt;p&gt;A nejlepší na tom je, že to i často funguje, takže chybu ani jen tak nezjistíte.&lt;/p&gt;&lt;p&gt;Pokud totiž použijete Ldc_I4_S instrukci (a mnoho dalších končících _S) tak druhý parametr Emit metody musí byt v tomto případě typu sbyte a ne int! Naštěstí .Net primárně vznikl na Little endian platformě, takže třeba číslo 42 bude zakódováno jako sekvence bytů 42, 0, 0, 0. Další ?prozřetelnost? je v tom, že 0 znamená Nop instrukci. Takže ve výsledku jsme nic neušetřili v délce kódu a místo jedné instrukce načtení malé konstanty necháme kompilovat ještě 3 Nopy navíc, ale kód alespoň funguje. V záporných hodnotách to je ovšem horší 255 je prefixref a její použití podle MSDN dokumentace by mělo vyvolat chybu (neověřoval jsem).&lt;/p&gt;&lt;p&gt;Takže správně má být:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;value&lt;/span&gt; &amp;gt;= -128 &amp;amp;&amp;amp; &lt;span class="kwrd"&gt;value&lt;/span&gt; &amp;lt;= 127)&lt;/pre&gt;&lt;pre class="csharpcode"&gt;    il.Emit(OpCodes.Ldc_I4_S, (&lt;span class="kwrd"&gt;sbyte&lt;/span&gt;)&lt;span class="kwrd"&gt;value&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&lt;/span&gt;    il.Emit(OpCodes.Ldc_I4, &lt;span class="kwrd"&gt;value&lt;/span&gt;);&lt;/pre&gt;&lt;p&gt;Pro kompletní funkci se koukněte sem: &lt;a href="https://github.com/Bobris/BTDB/blob/unstable/BTDB/IL/ILGeneratorExtensions.cs"&gt;https://github.com/Bobris/BTDB/blob/unstable/BTDB/IL/ILGeneratorExtensions.cs&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Jsou tam i další perly, ale o nich zas někdy příště.&lt;/p&gt;&lt;p&gt;BTW Stejný problém je řešen, ale chybně, zde: &lt;a href="http://stackoverflow.com/questions/1498162/c-ilgenerator-nop"&gt;http://stackoverflow.com/questions/1498162/c-ilgenerator-nop&lt;/a&gt;&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Přidej do&lt;/strong&gt; &lt;a href = "http://linkuj.cz/?id=linkuj&amp;amp;url=http://blog.vyvojar.cz/bobris/archive/2011/05/20/zaludnost-v-ilgenerator-emit.aspx&amp;amp;;title=Z%26%23225%3bludnost+v+ILGenerator.Emit" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/05/20/zaludnost-v-ilgenerator-emit.aspx"&gt;linkuj.cz!&lt;/a&gt; |  &lt;a href = "http://www.jagg.cz/bookmarks.php?action=add&amp;amp;address=http://blog.vyvojar.cz/bobris/archive/2011/05/20/zaludnost-v-ilgenerator-emit.aspx&amp;amp;;title=Z%26%23225%3bludnost+v+ILGenerator.Emit" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/05/20/zaludnost-v-ilgenerator-emit.aspx"&gt;jagg.cz!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://blog.vyvojar.cz/bobris/archive/2011/05/20/zaludnost-v-ilgenerator-emit.aspx&amp;amp;;title=Z%26%23225%3bludnost+v+ILGenerator.Emit" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/05/20/zaludnost-v-ilgenerator-emit.aspx"&gt;del.icio.us!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2011/05/20/zaludnost-v-ilgenerator-emit.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/05/20/zaludnost-v-ilgenerator-emit.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2011/05/20/zaludnost-v-ilgenerator-emit.aspx&amp;amp;title=Z%26%23225%3bludnost+v+ILGenerator.Emit" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/05/20/zaludnost-v-ilgenerator-emit.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://blog.vyvojar.cz/bobris/archive/2011/05/20/zaludnost-v-ilgenerator-emit.aspx&amp;amp;;title=Z%26%23225%3bludnost+v+ILGenerator.Emit" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/05/20/zaludnost-v-ilgenerator-emit.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://blog.vyvojar.cz/bobris/archive/2011/05/20/zaludnost-v-ilgenerator-emit.aspx&amp;amp;;title=Z%26%23225%3bludnost+v+ILGenerator.Emit&amp;amp;;top=1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/05/20/zaludnost-v-ilgenerator-emit.aspx"&gt;live it!&lt;/a&gt; |  &lt;a href = "mailto:?body=Thought you might like this: http://blog.vyvojar.cz/bobris/archive/2011/05/20/zaludnost-v-ilgenerator-emit.aspx&amp;amp;;subject=Z%26%23225%3bludnost+v+ILGenerator.Emit" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2011/05/20/zaludnost-v-ilgenerator-emit.aspx"&gt;email it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blog.vyvojar.cz/aggbug.aspx?PostID=238172" width="1" height="1"&gt;</description><category domain="http://blog.vyvojar.cz/bobris/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Reference counted string v C++</title><link>http://blog.vyvojar.cz/bobris/archive/2009/09/22/reference-counted-string-v-c.aspx</link><pubDate>Tue, 22 Sep 2009 20:39:00 GMT</pubDate><guid isPermaLink="false">99a92ff2-698a-48c2-8eaf-f3d9b6202627:235150</guid><dc:creator>bobris</dc:creator><slash:comments>2</slash:comments><comments>http://blog.vyvojar.cz/bobris/comments/235150.aspx</comments><wfw:commentRss>http://blog.vyvojar.cz/bobris/commentrss.aspx?PostID=235150</wfw:commentRss><wfw:comment>http://blog.vyvojar.cz/bobris/rsscomments.aspx?PostID=235150</wfw:comment><description>&lt;P&gt;Chtěl bych se s Vámi podělit o jednom velmi reálném měření z jedné “nejmenované” komerční aplikace. Je napsaná jak už asi tušíte v C++ hodně přes 2 miliony řádků. Pro práci se stringy tato aplikace používá vlastní implementaci na základě počítání počtu ukazatelů. Samotný string je tedy velký pouze jeden pointer. Pokud je ukazatel jen jeden, tak se chová na způsob .Netího StringBuilderu, jinak jako .Net string. Prázdný string má pak v sobě NULL. Aplikace to je více vláknová, proto musí být přičítání a odečítání počtu ukazatelů atomické. No ale taky lze tato aplikace pustit tak, že má potřebuje pouze jedno vlákno. Proto není od věci zkusit co by provedlo nahrazení atomických operací obyčejnými.&lt;/P&gt;
&lt;P&gt;Testy proběhly na 64bit Vistách, kompilátor je MSVC 2005, procesor pak přetaktované obstarožní Core2Duo E6400. InterlockedIncrement i InterlockedDecrement jsou &lt;A href="http://en.wikipedia.org/wiki/Intrinsic_function" target=_blank&gt;intrinsic&lt;/A&gt; (tzn. že je nativně kompilátor zná a přímo vkládá jejich kód místo volání API funkce). Samotný test je o tom načíst nějaká data a vytvořit z nich PDF (dost času se stráví kompresí, která žádné inkriminované operace neobsahuje). Vše je ve vyrovnávací paměti měřím až druhé spuštění, takže diskové operace by měly být zanedbatelné.&lt;/P&gt;
&lt;P&gt;Takže k výsledkům:&lt;/P&gt;
&lt;TABLE&gt;

&lt;TR&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;TD align=right&gt;Velikost Exe&lt;/TD&gt;
&lt;TD align=right&gt;Čas&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;32bit Atomic&lt;/TD&gt;
&lt;TD align=right&gt;25205 kB&lt;/TD&gt;
&lt;TD align=right&gt;17.7&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;32bit Plain&lt;/TD&gt;
&lt;TD align=right&gt;25295 kB&lt;/TD&gt;
&lt;TD align=right&gt;16.6&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;64bit Atomic&lt;/TD&gt;
&lt;TD align=right&gt;39696 kB&lt;/TD&gt;
&lt;TD align=right&gt;14.6&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;64bit Plain&lt;/TD&gt;
&lt;TD align=right&gt;39557 kB&lt;/TD&gt;
&lt;TD align=right&gt;13.1&lt;/TD&gt;&lt;/TR&gt;&lt;/TABLE&gt;
&lt;P&gt;Rozdíl velikosti exe souborů je rozhodně zajímavý 32bit aplikace se “zjednodušením” zvětšila a naopak 64bit se zmenšila. 64bit aplikace se pak zrychlila o víc než 32bit verze, těžko říct proč, samotný čítač je v obou verzích 32bitový. Velký rozdíl velikosti a i zrychlení 64bit verze oproti 32bit, pak připisuji především používání C++ vyjímek, v 32bit Windows totiž try catch není zadarmo.&lt;/P&gt;
&lt;P&gt;Pokud byste uvažovali o stejné aplikaci v .Netu, tak by to bylo rychlejší v tom, že by tam dokonce nebyl vůbec žádný čítač, pomalejší o konverze mezi stringem a StringBuilderem. Obecně se mi zdá, že pro více vláknové aplikace, výhoda GC oproti malloc/free, začíná být zajímavá.&lt;/P&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Přidej do&lt;/strong&gt; &lt;a href = "http://linkuj.cz/?id=linkuj&amp;amp;url=http://blog.vyvojar.cz/bobris/archive/2009/09/22/reference-counted-string-v-c.aspx&amp;amp;;title=Reference+counted+string+v+C%2b%2b" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/09/22/reference-counted-string-v-c.aspx"&gt;linkuj.cz!&lt;/a&gt; |  &lt;a href = "http://www.jagg.cz/bookmarks.php?action=add&amp;amp;address=http://blog.vyvojar.cz/bobris/archive/2009/09/22/reference-counted-string-v-c.aspx&amp;amp;;title=Reference+counted+string+v+C%2b%2b" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/09/22/reference-counted-string-v-c.aspx"&gt;jagg.cz!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://blog.vyvojar.cz/bobris/archive/2009/09/22/reference-counted-string-v-c.aspx&amp;amp;;title=Reference+counted+string+v+C%2b%2b" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/09/22/reference-counted-string-v-c.aspx"&gt;del.icio.us!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/09/22/reference-counted-string-v-c.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/09/22/reference-counted-string-v-c.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/09/22/reference-counted-string-v-c.aspx&amp;amp;title=Reference+counted+string+v+C%2b%2b" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/09/22/reference-counted-string-v-c.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://blog.vyvojar.cz/bobris/archive/2009/09/22/reference-counted-string-v-c.aspx&amp;amp;;title=Reference+counted+string+v+C%2b%2b" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/09/22/reference-counted-string-v-c.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://blog.vyvojar.cz/bobris/archive/2009/09/22/reference-counted-string-v-c.aspx&amp;amp;;title=Reference+counted+string+v+C%2b%2b&amp;amp;;top=1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/09/22/reference-counted-string-v-c.aspx"&gt;live it!&lt;/a&gt; |  &lt;a href = "mailto:?body=Thought you might like this: http://blog.vyvojar.cz/bobris/archive/2009/09/22/reference-counted-string-v-c.aspx&amp;amp;;subject=Reference+counted+string+v+C%2b%2b" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/09/22/reference-counted-string-v-c.aspx"&gt;email it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blog.vyvojar.cz/aggbug.aspx?PostID=235150" width="1" height="1"&gt;</description></item><item><title>Běž a uklízej</title><link>http://blog.vyvojar.cz/bobris/archive/2009/08/15/b-a-ukl-zej.aspx</link><pubDate>Sat, 15 Aug 2009 19:45:00 GMT</pubDate><guid isPermaLink="false">99a92ff2-698a-48c2-8eaf-f3d9b6202627:234630</guid><dc:creator>bobris</dc:creator><slash:comments>2</slash:comments><comments>http://blog.vyvojar.cz/bobris/comments/234630.aspx</comments><wfw:commentRss>http://blog.vyvojar.cz/bobris/commentrss.aspx?PostID=234630</wfw:commentRss><wfw:comment>http://blog.vyvojar.cz/bobris/rsscomments.aspx?PostID=234630</wfw:comment><description>&lt;P&gt;Chtěl bych vám představit jednu z nejlepších novinek .Netu 4.0 a zajímavé je, že v seznamu &lt;A title=http://msdn.microsoft.com/en-us/library/dd409230(VS.100).aspx href="http://msdn.microsoft.com/en-us/library/dd409230(VS.100).aspx" target=_blank&gt;What's New in the .NET Framework 4&lt;/A&gt; ji ani nenajdete.&lt;/P&gt;
&lt;P&gt;Nejdříve ale zase ukázkový kód, spustitelný v .Net 3.5:&lt;/P&gt;
&lt;DIV style="PADDING-BOTTOM:5px;PADDING-LEFT:5px;WIDTH:98%;PADDING-RIGHT:5px;DISPLAY:block;FLOAT:none;MARGIN-LEFT:auto;MARGIN-RIGHT:auto;PADDING-TOP:5px;" id=scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:fbc6cdc2-e9ae-4767-b0ff-813b97072239 class=wlWriterEditableSmartContent&gt;
&lt;DIV style="BORDER-BOTTOM:#000080 1px solid;BORDER-LEFT:#000080 1px solid;FONT-FAMILY:'Courier New', Courier, Monospace;FONT-SIZE:10pt;BORDER-TOP:#000080 1px solid;BORDER-RIGHT:#000080 1px solid;"&gt;
&lt;DIV style="PADDING-BOTTOM:0px;PADDING-LEFT:0px;PADDING-RIGHT:0px;BACKGROUND:#ddd;MAX-HEIGHT:400px;OVERFLOW:scroll;PADDING-TOP:0px;"&gt;
&lt;OL style="MARGIN:0px 0px 0px 35px;BACKGROUND:#ffffff;"&gt;
&lt;LI&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR:#0000ff;"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;void&lt;/SPAN&gt; Main(&lt;SPAN style="COLOR:#0000ff;"&gt;string&lt;/SPAN&gt;[] args)&lt;/LI&gt;
&lt;LI style="BACKGROUND:#f3f3f3;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/LI&gt;
&lt;LI&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR:#0000ff;"&gt;for&lt;/SPAN&gt; (&lt;SPAN style="COLOR:#0000ff;"&gt;int&lt;/SPAN&gt; i = 0; i &amp;lt; 100000; i++)&lt;/LI&gt;
&lt;LI style="BACKGROUND:#f3f3f3;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/LI&gt;
&lt;LI&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR:#0000ff;"&gt;if&lt;/SPAN&gt; (i % 1000 == 0) &lt;SPAN style="COLOR:#2b91af;"&gt;Console&lt;/SPAN&gt;.WriteLine(i);&lt;/LI&gt;
&lt;LI style="BACKGROUND:#f3f3f3;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR:#2b91af;"&gt;AssemblyBuilder&lt;/SPAN&gt; ab = &lt;SPAN style="COLOR:#2b91af;"&gt;AppDomain&lt;/SPAN&gt;.CurrentDomain.DefineDynamicAssembly(&lt;/LI&gt;
&lt;LI&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR:#0000ff;"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;AssemblyName&lt;/SPAN&gt;(&lt;SPAN style="COLOR:#a31515;"&gt;"DynAsm"&lt;/SPAN&gt;+i.ToString()), &lt;SPAN style="COLOR:#2b91af;"&gt;AssemblyBuilderAccess&lt;/SPAN&gt;.Run);&lt;/LI&gt;
&lt;LI style="BACKGROUND:#f3f3f3;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR:#2b91af;"&gt;ModuleBuilder&lt;/SPAN&gt; mb = ab.DefineDynamicModule(&lt;SPAN style="COLOR:#a31515;"&gt;"DynMod"&lt;/SPAN&gt;+i.ToString());&lt;/LI&gt;
&lt;LI&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR:#2b91af;"&gt;TypeBuilder&lt;/SPAN&gt; tb = mb.DefineType(&lt;SPAN style="COLOR:#a31515;"&gt;"DynType"&lt;/SPAN&gt; + i.ToString(), &lt;SPAN style="COLOR:#2b91af;"&gt;TypeAttributes&lt;/SPAN&gt;.Public);&lt;/LI&gt;
&lt;LI style="BACKGROUND:#f3f3f3;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tb.DefineField(&lt;SPAN style="COLOR:#a31515;"&gt;"F1"&lt;/SPAN&gt;, &lt;SPAN style="COLOR:#0000ff;"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR:#0000ff;"&gt;string&lt;/SPAN&gt;), &lt;SPAN style="COLOR:#2b91af;"&gt;FieldAttributes&lt;/SPAN&gt;.Public);&lt;/LI&gt;
&lt;LI&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tb.DefineField(&lt;SPAN style="COLOR:#a31515;"&gt;"F2"&lt;/SPAN&gt;, &lt;SPAN style="COLOR:#0000ff;"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR:#0000ff;"&gt;int&lt;/SPAN&gt;), &lt;SPAN style="COLOR:#2b91af;"&gt;FieldAttributes&lt;/SPAN&gt;.Public);&lt;/LI&gt;
&lt;LI style="BACKGROUND:#f3f3f3;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR:#2b91af;"&gt;MethodBuilder&lt;/SPAN&gt; metb = tb.DefineMethod(&lt;SPAN style="COLOR:#a31515;"&gt;"create"&lt;/SPAN&gt;,&lt;/LI&gt;
&lt;LI&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR:#2b91af;"&gt;MethodAttributes&lt;/SPAN&gt;.Public | &lt;SPAN style="COLOR:#2b91af;"&gt;MethodAttributes&lt;/SPAN&gt;.Static, tb, System.&lt;SPAN style="COLOR:#2b91af;"&gt;Type&lt;/SPAN&gt;.EmptyTypes);&lt;/LI&gt;
&lt;LI style="BACKGROUND:#f3f3f3;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR:#0000ff;"&gt;var&lt;/SPAN&gt; ilg = metb.GetILGenerator();&lt;/LI&gt;
&lt;LI&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ilg.Emit(&lt;SPAN style="COLOR:#2b91af;"&gt;OpCodes&lt;/SPAN&gt;.Newobj, tb.DefineDefaultConstructor(&lt;SPAN style="COLOR:#2b91af;"&gt;MethodAttributes&lt;/SPAN&gt;.Public));&lt;/LI&gt;
&lt;LI style="BACKGROUND:#f3f3f3;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ilg.Emit(&lt;SPAN style="COLOR:#2b91af;"&gt;OpCodes&lt;/SPAN&gt;.Ret);&lt;/LI&gt;
&lt;LI&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR:#2b91af;"&gt;Type&lt;/SPAN&gt; t = tb.CreateType();&lt;/LI&gt;
&lt;LI style="BACKGROUND:#f3f3f3;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR:#0000ff;"&gt;var&lt;/SPAN&gt; del = (&lt;SPAN style="COLOR:#2b91af;"&gt;Func&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR:#0000ff;"&gt;object&lt;/SPAN&gt;&amp;gt;)&lt;SPAN style="COLOR:#2b91af;"&gt;Delegate&lt;/SPAN&gt;.CreateDelegate(&lt;SPAN style="COLOR:#0000ff;"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR:#2b91af;"&gt;Func&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR:#0000ff;"&gt;object&lt;/SPAN&gt;&amp;gt;), t.GetMethod(&lt;SPAN style="COLOR:#a31515;"&gt;"create"&lt;/SPAN&gt;));&lt;/LI&gt;
&lt;LI&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR:#0000ff;"&gt;object&lt;/SPAN&gt; d = del();&lt;/LI&gt;
&lt;LI style="BACKGROUND:#f3f3f3;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/LI&gt;
&lt;LI&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/LI&gt;
&lt;LI style="BACKGROUND:#f3f3f3;"&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;Tento prográmek vytváří nové typy, nakonec pak i vytváří jejich instance. Pokud to spustím v .Netu 3.5 tak před 7000 iterací dojde paměť. To samé v .Netu 4.0 beta 1 skončí až před 21000 iterací, takže třikrát méně paměťově náročnější.&lt;/P&gt;
&lt;P&gt;No a konečně se dostáváme k té novince nahraďme AssemblyBuilderAccess.Run za AssemblyBuilderAccess.RunAndCollect a paměť nedojde nikdy. Osciluje kolem 7,5 MB. Nový mód RunAndCollect má pár &lt;A href="http://msdn.microsoft.com/en-us/library/dd554932(VS.100).aspx#restrictions" target=_blank&gt;omezení&lt;/A&gt;, ale nic s čím by se nedalo žít. Hlavně to nenechte běžet dlouho v debuggeru, protože to pak dojde pamět jemu kvůli symbolům z nových assembly.&lt;/P&gt;
&lt;P&gt;DynamicMethod v .Net 2.0 byl začátek, ale tohle konečně umožňuje vytvářet dynamicky optimalizovatelné programy bez zpomalení komunikací mezi AppDomainy. SkyNet se blíží …&lt;/P&gt;
&lt;P&gt;Ještě upozornění, pokud na konec cyklu dopíšete:&lt;/P&gt;
&lt;DIV style="PADDING-BOTTOM:5px;PADDING-LEFT:5px;WIDTH:98%;PADDING-RIGHT:5px;DISPLAY:block;FLOAT:none;MARGIN-LEFT:auto;MARGIN-RIGHT:auto;PADDING-TOP:5px;" id=scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1f2e5cff-3fd8-4d3f-9b84-fc3370b8d9f7 class=wlWriterEditableSmartContent&gt;
&lt;DIV style="BORDER-BOTTOM:#000080 1px solid;BORDER-LEFT:#000080 1px solid;FONT-FAMILY:'Courier New', Courier, Monospace;FONT-SIZE:10pt;BORDER-TOP:#000080 1px solid;BORDER-RIGHT:#000080 1px solid;"&gt;
&lt;DIV style="PADDING-BOTTOM:2px;BACKGROUND-COLOR:#ffffff;PADDING-LEFT:5px;PADDING-RIGHT:5px;WHITE-SPACE:nowrap;MAX-HEIGHT:200px;OVERFLOW:scroll;PADDING-TOP:2px;"&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR:#0000ff;"&gt;dynamic&lt;/SPAN&gt; dd = d;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dd.F1 = &lt;SPAN style="COLOR:#a31515;"&gt;"Hello"&lt;/SPAN&gt;;&lt;BR&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;Tak to sice funguje, ale zabrání to úklidu, takže paměť dojde před 7000 iterací. Pravděpodobně implementace dynamic si drží vygenerované metody navždy. Možná to ještě opraví, ale ono stejně kombinovat DynamicAssembly s dynamic nedává smysl. Když už jste na úrovni, že dokážete používat DynamicAssembly, tak si můžete naprogramovat vlastní dynamic.&lt;/P&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Přidej do&lt;/strong&gt; &lt;a href = "http://linkuj.cz/?id=linkuj&amp;amp;url=http://blog.vyvojar.cz/bobris/archive/2009/08/15/b-a-ukl-zej.aspx&amp;amp;;title=B%c4%9b%c5%be+a+ukl%26%23237%3bzej" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/08/15/b-a-ukl-zej.aspx"&gt;linkuj.cz!&lt;/a&gt; |  &lt;a href = "http://www.jagg.cz/bookmarks.php?action=add&amp;amp;address=http://blog.vyvojar.cz/bobris/archive/2009/08/15/b-a-ukl-zej.aspx&amp;amp;;title=B%c4%9b%c5%be+a+ukl%26%23237%3bzej" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/08/15/b-a-ukl-zej.aspx"&gt;jagg.cz!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://blog.vyvojar.cz/bobris/archive/2009/08/15/b-a-ukl-zej.aspx&amp;amp;;title=B%c4%9b%c5%be+a+ukl%26%23237%3bzej" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/08/15/b-a-ukl-zej.aspx"&gt;del.icio.us!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/08/15/b-a-ukl-zej.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/08/15/b-a-ukl-zej.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/08/15/b-a-ukl-zej.aspx&amp;amp;title=B%c4%9b%c5%be+a+ukl%26%23237%3bzej" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/08/15/b-a-ukl-zej.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://blog.vyvojar.cz/bobris/archive/2009/08/15/b-a-ukl-zej.aspx&amp;amp;;title=B%c4%9b%c5%be+a+ukl%26%23237%3bzej" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/08/15/b-a-ukl-zej.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://blog.vyvojar.cz/bobris/archive/2009/08/15/b-a-ukl-zej.aspx&amp;amp;;title=B%c4%9b%c5%be+a+ukl%26%23237%3bzej&amp;amp;;top=1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/08/15/b-a-ukl-zej.aspx"&gt;live it!&lt;/a&gt; |  &lt;a href = "mailto:?body=Thought you might like this: http://blog.vyvojar.cz/bobris/archive/2009/08/15/b-a-ukl-zej.aspx&amp;amp;;subject=B%c4%9b%c5%be+a+ukl%26%23237%3bzej" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/08/15/b-a-ukl-zej.aspx"&gt;email it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blog.vyvojar.cz/aggbug.aspx?PostID=234630" width="1" height="1"&gt;</description></item><item><title>První dojmy z VS2010 Beta 1</title><link>http://blog.vyvojar.cz/bobris/archive/2009/05/19/prvn-dojmy-z-vs2010-beta-1.aspx</link><pubDate>Tue, 19 May 2009 21:41:43 GMT</pubDate><guid isPermaLink="false">99a92ff2-698a-48c2-8eaf-f3d9b6202627:230251</guid><dc:creator>bobris</dc:creator><slash:comments>24</slash:comments><comments>http://blog.vyvojar.cz/bobris/comments/230251.aspx</comments><wfw:commentRss>http://blog.vyvojar.cz/bobris/commentrss.aspx?PostID=230251</wfw:commentRss><wfw:comment>http://blog.vyvojar.cz/bobris/rsscomments.aspx?PostID=230251</wfw:comment><description>&lt;p&gt;1.2 GB iso image… 3 vynucené restarty … a jde se na věc …&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.vyvojar.cz/blogs/bobris/image_048FDE4C.png"&gt;&lt;img title="image" style="border-right:0px;border-top:0px;display:inline;border-left:0px;border-bottom:0px;" height="576" alt="image" src="http://blog.vyvojar.cz/blogs/bobris/image_thumb_7FAD2A8F.png" width="786" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Nejdříve jsem si musel promnout oči, protože jsem si myslel, že vidím nějak rozostřeně. Ano bylo to mé první setkání s WPF v “seriózní” aplikaci. A bude to chtít hódně zvykání na text o kvalitě analogového signálu v nenativním rozlišení LCDčka :-). Ale zato na první pohled poznáte co je WPF a co je “staré”. Customizace toolbaru je bohužel v Betě vypnutá. Povšimněte si pak selekce s gradientovou výplní, no jo když ono je to tak jednoduchý to ve WPF udělat, tak proč to tím “nevylepšit”. Takhle z aplikací alespoň už nejde poznat jestli máte vadný podsvícení nebo to je umělecký záměr.&lt;/p&gt;  &lt;p&gt;Po prvním restartu během instalace již je nainstalovaný .Net 4.0. Takže jsem vyzkoušel Reflektor. Částečně jede, sem tam hází výjimky, takže jsem zvědav jak se Red Gate pochlapí, Lutz by v tuhle dobu již měl dávno plně funkční verzi venku …&lt;/p&gt;  &lt;p&gt;No ještě jeden screenshot s C++0x auto. Bohužel kvůli muzeálním platformám je tohle jen malé uslintnutí nad něčím co jen tak nebudeme v robotě používat … (Font editoru jsem zvětšil z 10pt na 11pt, aby se na to dalo koukat)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.vyvojar.cz/blogs/bobris/image_0908EFC4.png"&gt;&lt;img title="image" style="border-right:0px;border-top:0px;display:inline;border-left:0px;border-bottom:0px;" height="667" alt="image" src="http://blog.vyvojar.cz/blogs/bobris/image_thumb_244148C5.png" width="788" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Intelisence v takhle krátkým zdrojáku jede dobře, ale to šla i v VS2008. Nově pak i v reálném čase podtrhává chyby. Na větší projekty se zatím nedostalo času …&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Přidej do&lt;/strong&gt; &lt;a href = "http://linkuj.cz/?id=linkuj&amp;amp;url=http://blog.vyvojar.cz/bobris/archive/2009/05/19/prvn-dojmy-z-vs2010-beta-1.aspx&amp;amp;;title=Prvn%26%23237%3b+dojmy+z+VS2010+Beta+1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/05/19/prvn-dojmy-z-vs2010-beta-1.aspx"&gt;linkuj.cz!&lt;/a&gt; |  &lt;a href = "http://www.jagg.cz/bookmarks.php?action=add&amp;amp;address=http://blog.vyvojar.cz/bobris/archive/2009/05/19/prvn-dojmy-z-vs2010-beta-1.aspx&amp;amp;;title=Prvn%26%23237%3b+dojmy+z+VS2010+Beta+1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/05/19/prvn-dojmy-z-vs2010-beta-1.aspx"&gt;jagg.cz!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://blog.vyvojar.cz/bobris/archive/2009/05/19/prvn-dojmy-z-vs2010-beta-1.aspx&amp;amp;;title=Prvn%26%23237%3b+dojmy+z+VS2010+Beta+1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/05/19/prvn-dojmy-z-vs2010-beta-1.aspx"&gt;del.icio.us!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/05/19/prvn-dojmy-z-vs2010-beta-1.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/05/19/prvn-dojmy-z-vs2010-beta-1.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/05/19/prvn-dojmy-z-vs2010-beta-1.aspx&amp;amp;title=Prvn%26%23237%3b+dojmy+z+VS2010+Beta+1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/05/19/prvn-dojmy-z-vs2010-beta-1.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://blog.vyvojar.cz/bobris/archive/2009/05/19/prvn-dojmy-z-vs2010-beta-1.aspx&amp;amp;;title=Prvn%26%23237%3b+dojmy+z+VS2010+Beta+1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/05/19/prvn-dojmy-z-vs2010-beta-1.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://blog.vyvojar.cz/bobris/archive/2009/05/19/prvn-dojmy-z-vs2010-beta-1.aspx&amp;amp;;title=Prvn%26%23237%3b+dojmy+z+VS2010+Beta+1&amp;amp;;top=1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/05/19/prvn-dojmy-z-vs2010-beta-1.aspx"&gt;live it!&lt;/a&gt; |  &lt;a href = "mailto:?body=Thought you might like this: http://blog.vyvojar.cz/bobris/archive/2009/05/19/prvn-dojmy-z-vs2010-beta-1.aspx&amp;amp;;subject=Prvn%26%23237%3b+dojmy+z+VS2010+Beta+1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/05/19/prvn-dojmy-z-vs2010-beta-1.aspx"&gt;email it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blog.vyvojar.cz/aggbug.aspx?PostID=230251" width="1" height="1"&gt;</description></item><item><title>Ukazatel na funkci 5</title><link>http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-5.aspx</link><pubDate>Wed, 15 Apr 2009 21:07:00 GMT</pubDate><guid isPermaLink="false">99a92ff2-698a-48c2-8eaf-f3d9b6202627:229410</guid><dc:creator>bobris</dc:creator><slash:comments>0</slash:comments><comments>http://blog.vyvojar.cz/bobris/comments/229410.aspx</comments><wfw:commentRss>http://blog.vyvojar.cz/bobris/commentrss.aspx?PostID=229410</wfw:commentRss><wfw:comment>http://blog.vyvojar.cz/bobris/rsscomments.aspx?PostID=229410</wfw:comment><description>&lt;P&gt;Po Googlovaní toho tailcallu, jsem našel jen pár dalších stěžovatelů si na jejich rychlost. Potenciálně tuším co by mohl dělat “foobar” – profiler hook, i když profiler sem připojený neměl, možná to je kvůli tomu ze CLR (ani 4.0) nepodporuje “rejit”, takže ten hook tam musí být již od začátku. No a taky jsem se dočetl, že by 64bit tailcall měl být rychlejší než 32bit. &lt;STRIKE&gt;No takže to je přesně obráceně a to tak, že asi o 500%, takže 64bit tailcall je ještě 6 krát pomalejší než 32bitový na tom příkladu z minula, to už mě hlava nebere…&lt;/STRIKE&gt; Tak to byla moje chyba, je to opravdu tak, ze 64bit je rychlejší než 32bit tailcall a to více než 20 krát v našem příkladu, což vypadá již dost optimalně.&lt;/P&gt;
&lt;P&gt;Pár linků …&lt;/P&gt;
&lt;P&gt;Podobně podrobné vysvětlení: &lt;A title=http://barrkel.blogspot.com/2006/05/clr-tailcall-optimization-or-lack.html href="http://barrkel.blogspot.com/2006/05/clr-tailcall-optimization-or-lack.html"&gt;http://barrkel.blogspot.com/2006/05/clr-tailcall-optimization-or-lack.html&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Bug na connectu od Nemerle lidí: &lt;A title=http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=98236 href="http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=98236"&gt;http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=98236&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Vysvětlení problému a vysvětlení, že jeho řesení musí počkat za .Net 2.0 &lt;A href="http://blogs.msdn.com/shrib/archive/2005/01/25/360370.aspx"&gt;http://blogs.msdn.com/shrib/archive/2005/01/25/360370.aspx&lt;/A&gt;&lt;/P&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Přidej do&lt;/strong&gt; &lt;a href = "http://linkuj.cz/?id=linkuj&amp;amp;url=http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-5.aspx&amp;amp;;title=Ukazatel+na+funkci+5" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-5.aspx"&gt;linkuj.cz!&lt;/a&gt; |  &lt;a href = "http://www.jagg.cz/bookmarks.php?action=add&amp;amp;address=http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-5.aspx&amp;amp;;title=Ukazatel+na+funkci+5" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-5.aspx"&gt;jagg.cz!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-5.aspx&amp;amp;;title=Ukazatel+na+funkci+5" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-5.aspx"&gt;del.icio.us!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-5.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-5.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-5.aspx&amp;amp;title=Ukazatel+na+funkci+5" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-5.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-5.aspx&amp;amp;;title=Ukazatel+na+funkci+5" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-5.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-5.aspx&amp;amp;;title=Ukazatel+na+funkci+5&amp;amp;;top=1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-5.aspx"&gt;live it!&lt;/a&gt; |  &lt;a href = "mailto:?body=Thought you might like this: http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-5.aspx&amp;amp;;subject=Ukazatel+na+funkci+5" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-5.aspx"&gt;email it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blog.vyvojar.cz/aggbug.aspx?PostID=229410" width="1" height="1"&gt;</description><category domain="http://blog.vyvojar.cz/bobris/archive/tags/F_2300_/default.aspx">F#</category></item><item><title>Ukazatel na funkci 4</title><link>http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-4.aspx</link><pubDate>Tue, 14 Apr 2009 23:16:24 GMT</pubDate><guid isPermaLink="false">99a92ff2-698a-48c2-8eaf-f3d9b6202627:229386</guid><dc:creator>bobris</dc:creator><slash:comments>3</slash:comments><comments>http://blog.vyvojar.cz/bobris/comments/229386.aspx</comments><wfw:commentRss>http://blog.vyvojar.cz/bobris/commentrss.aspx?PostID=229386</wfw:commentRss><wfw:comment>http://blog.vyvojar.cz/bobris/rsscomments.aspx?PostID=229386</wfw:comment><description>&lt;p&gt;Jak tedy může být implementovaný tailcall. Zjištění nebude jednoduché, kompilátor F# je dobře připraven to neukázat jen tak zadarmo. Když totiž začneme s jednoduchou zkouškou:&lt;/p&gt;  &lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;   &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;#light&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;open&lt;/span&gt; System&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;let&lt;/span&gt; &lt;span style="color:blue;"&gt;rec&lt;/span&gt; fn1 i max=&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;if&lt;/span&gt; i&amp;lt;max &lt;span style="color:blue;"&gt;then&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; fn2 (i+1) max &lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;else&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; max&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;and&lt;/span&gt; fn2 i max=&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;if&lt;/span&gt; i&amp;lt;max &lt;span style="color:blue;"&gt;then&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; fn1 (i+1) max&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;else&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; max&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt; fn1 0 10000000 |&amp;gt; ignore&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Tak ta se funkce fn2 přeloží jako while cyklus s rozvinutou fn1 a jediný tailcall je ve fn1 při volání fn2, ale ten si nezměříme, když je jen jeden. Mimochodem kdy myslíte že se dočkáme kompilátoru, který to zoptimalizuje na: let fn1 x y=y (já jsem pesimista s odhadem od 10 do 15 let :-))&lt;/p&gt;

&lt;p&gt;Tak to trochu zjednodušíme a zároveň pro F# zesložitíme:&lt;/p&gt;

&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;#light&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;open&lt;/span&gt; System&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; Recursive(max) =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;abstract&lt;/span&gt; run: int &lt;span style="color:blue;"&gt;-&amp;gt;&lt;/span&gt; int&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;default&lt;/span&gt; this.run(i)=&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;if&lt;/span&gt; i&amp;lt;max &lt;span style="color:blue;"&gt;then&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.run(i+1)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;else&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; i&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;let&lt;/span&gt; sw = &lt;span style="color:blue;"&gt;new&lt;/span&gt; Diagnostics.Stopwatch()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;let&lt;/span&gt; r=&lt;span style="color:blue;"&gt;new&lt;/span&gt; Recursive(10000000)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt; System.GC.Collect(); System.GC.WaitForPendingFinalizers()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt; sw.Start()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt; r.run 0 |&amp;gt;ignore&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt; sw.Stop()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt; printf &lt;span style="color:maroon;"&gt;&amp;quot;%d&amp;quot;&lt;/span&gt; sw.ElapsedMilliseconds&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;To už si netroufne zoptimalizovat (ani se nedivím) a trvá to 221ms (poměrně přesně (609ms (F#)-184ms(C#)) /2 (byli tam 2 tailcall na iteraci) = 212ms) . V C# a ani v Monu tohle nezkoušejte pokud nechcete vidět toto:&lt;/p&gt;

&lt;p&gt;Unhandled Exception: System.StackOverflowException: The requested operation caused a stack overflow. &lt;/p&gt;

&lt;p&gt;&amp;#160; at Program+Recursive.run (Int32 i) [0x00000]&amp;#160; (tento řádek se tisickrát opakuje :-)&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Jak tedy vypadá metoda run v assembleru:&lt;/p&gt;

&lt;p&gt;03520160 55&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; push&amp;#160;&amp;#160;&amp;#160; ebp // klasický vstup funkce 
  &lt;br /&gt;03520161 8bec&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mov&amp;#160;&amp;#160;&amp;#160;&amp;#160; ebp,esp 

  &lt;br /&gt;03520163 57&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; push&amp;#160;&amp;#160;&amp;#160; edi // zazálohujeme si edi, esi, ebx – konvence .Netu 

  &lt;br /&gt;03520164 56&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; push&amp;#160;&amp;#160;&amp;#160; esi 

  &lt;br /&gt;03520165 53&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; push&amp;#160;&amp;#160;&amp;#160; ebx 

  &lt;br /&gt;03520166 8bc2&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mov&amp;#160;&amp;#160;&amp;#160;&amp;#160; eax,edx // edx je první parametr&amp;#160; = i 

  &lt;br /&gt;03520168 3b4104&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cmp&amp;#160;&amp;#160;&amp;#160;&amp;#160; eax,dword ptr [ecx+4] // ecx je this a první member je na pozici 4, pozice 0 je vyhrazena virtuální tabulce metod 

  &lt;br /&gt;0352016b 7d26&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; jge&amp;#160;&amp;#160;&amp;#160;&amp;#160; 03520193 // skoč když i&amp;gt;=max 

  &lt;br /&gt;0352016d 40&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; inc&amp;#160;&amp;#160;&amp;#160;&amp;#160; eax // +1 

  &lt;br /&gt;0352016e 8bd0&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mov&amp;#160;&amp;#160;&amp;#160;&amp;#160; edx,eax // nové i = i+1, ecx zůstává zachováno 

  &lt;br /&gt;03520170 8b01&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mov&amp;#160;&amp;#160;&amp;#160;&amp;#160; eax,dword ptr [ecx] // ukazatel na tabulku virtualních metod 

  &lt;br /&gt;03520172 8b4038&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mov&amp;#160;&amp;#160;&amp;#160;&amp;#160; eax,dword ptr [eax+38h] // asi něco jako id definice metody run 

  &lt;br /&gt;03520175 6a00&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; push&amp;#160;&amp;#160;&amp;#160; 0 // asi něco jako rozdíl počtu parametrů aktuální funkce a té tailcall volané 

  &lt;br /&gt;03520177 6a00&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; push&amp;#160;&amp;#160;&amp;#160; 0 // tak podobně 

  &lt;br /&gt;03520179 6a01&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; push&amp;#160;&amp;#160;&amp;#160; 1 

  &lt;br /&gt;0352017b 50&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; push&amp;#160;&amp;#160;&amp;#160; eax 

  &lt;br /&gt;0352017c 833d9c333b7a00&amp;#160; cmp&amp;#160;&amp;#160;&amp;#160;&amp;#160; dword ptr [mscorwks!GetHistoryFileDirectory+0xf0998 (7a3b339c)],0 // tenhle test mě fakt nenapadá na co by mohl být 

  &lt;br /&gt;03520183 7409&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; je&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0352018e // tady to vždy skočí 

  &lt;br /&gt;03520185 51&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; push&amp;#160;&amp;#160;&amp;#160; ecx // uložit nové this a parametry 

  &lt;br /&gt;03520186 52&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; push&amp;#160;&amp;#160;&amp;#160; edx 

  &lt;br /&gt;03520187 e847c8ba76&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; call&amp;#160;&amp;#160;&amp;#160; mscorwks!CorLaunchApplication+0x111bd (7a0cc9d3) // foobar :) 

  &lt;br /&gt;0352018c 5a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pop&amp;#160;&amp;#160;&amp;#160;&amp;#160; edx // obnovit this a parametry 

  &lt;br /&gt;0352018d 59&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pop&amp;#160;&amp;#160;&amp;#160;&amp;#160; ecx 

  &lt;br /&gt;0352018e e8fd269576&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; call&amp;#160;&amp;#160;&amp;#160; mscorwks+0x2890 (79e72890) // a tohle je ta obecná relativně pomalá funkce co provede tailcall případně JITuje pokud je potřeba 

  &lt;br /&gt;03520193 5b&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pop&amp;#160;&amp;#160;&amp;#160;&amp;#160; ebx // klasický výstup z funkce 

  &lt;br /&gt;03520194 5e&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pop&amp;#160;&amp;#160;&amp;#160;&amp;#160; esi 

  &lt;br /&gt;03520195 5f&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pop&amp;#160;&amp;#160;&amp;#160;&amp;#160; edi 

  &lt;br /&gt;03520196 5d&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pop&amp;#160;&amp;#160;&amp;#160;&amp;#160; ebp 

  &lt;br /&gt;03520197 c3&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ret&lt;/p&gt;

&lt;p&gt;Ta “pomalá” funkce na tailcall je pak asi dalších 20 instrukcí co se provádí v našem případě. Asi to “musí” být takto složité, ono správně vyřešit asynchronní výjimky nebude žádná sranda. Ale jak již jsem řekl F# to moc nepomáhá.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Přidej do&lt;/strong&gt; &lt;a href = "http://linkuj.cz/?id=linkuj&amp;amp;url=http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-4.aspx&amp;amp;;title=Ukazatel+na+funkci+4" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-4.aspx"&gt;linkuj.cz!&lt;/a&gt; |  &lt;a href = "http://www.jagg.cz/bookmarks.php?action=add&amp;amp;address=http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-4.aspx&amp;amp;;title=Ukazatel+na+funkci+4" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-4.aspx"&gt;jagg.cz!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-4.aspx&amp;amp;;title=Ukazatel+na+funkci+4" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-4.aspx"&gt;del.icio.us!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-4.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-4.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-4.aspx&amp;amp;title=Ukazatel+na+funkci+4" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-4.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-4.aspx&amp;amp;;title=Ukazatel+na+funkci+4" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-4.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-4.aspx&amp;amp;;title=Ukazatel+na+funkci+4&amp;amp;;top=1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-4.aspx"&gt;live it!&lt;/a&gt; |  &lt;a href = "mailto:?body=Thought you might like this: http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-4.aspx&amp;amp;;subject=Ukazatel+na+funkci+4" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/15/ukazatel-na-funkci-4.aspx"&gt;email it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blog.vyvojar.cz/aggbug.aspx?PostID=229386" width="1" height="1"&gt;</description><category domain="http://blog.vyvojar.cz/bobris/archive/tags/F_2300_/default.aspx">F#</category></item><item><title>Ukazatel na funkci 3</title><link>http://blog.vyvojar.cz/bobris/archive/2009/04/14/ukazatel-na-funkci-3.aspx</link><pubDate>Mon, 13 Apr 2009 22:37:45 GMT</pubDate><guid isPermaLink="false">99a92ff2-698a-48c2-8eaf-f3d9b6202627:229373</guid><dc:creator>bobris</dc:creator><slash:comments>3</slash:comments><comments>http://blog.vyvojar.cz/bobris/comments/229373.aspx</comments><wfw:commentRss>http://blog.vyvojar.cz/bobris/commentrss.aspx?PostID=229373</wfw:commentRss><wfw:comment>http://blog.vyvojar.cz/bobris/rsscomments.aspx?PostID=229373</wfw:comment><description>&lt;p&gt;Další pokračování s dalšími objevy. Chtěl jsem ještě zjistit jako to je s tím přetypováním z prvního dílu. Aby se mi to lépe v Assembleru ladilo, tak jsem přepsal tento F# v C#:&lt;/p&gt;  &lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;   &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;#light&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;open&lt;/span&gt; System&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;let&lt;/span&gt; &lt;span style="color:blue;"&gt;inline&lt;/span&gt; add x y = x + y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;let&lt;/span&gt; &lt;span style="color:blue;"&gt;inline&lt;/span&gt; sub x y = x - y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; test() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; &lt;span style="color:blue;"&gt;mutable&lt;/span&gt; op = add&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; addop = add&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; subop = sub&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;member&lt;/span&gt; &lt;span style="color:blue;"&gt;private&lt;/span&gt; this.testiter (i:int) =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op i i&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- subop&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op i i&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- addop&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;member&lt;/span&gt; &lt;span style="color:blue;"&gt;public&lt;/span&gt; this.test max =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;for&lt;/span&gt; ii &lt;span style="color:blue;"&gt;in&lt;/span&gt; 0..max-1 &lt;span style="color:blue;"&gt;do&lt;/span&gt; this.testiter ii&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 19&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 20&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;let&lt;/span&gt; sw = &lt;span style="color:blue;"&gt;new&lt;/span&gt; Diagnostics.Stopwatch()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 21&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;let&lt;/span&gt; t=&lt;span style="color:blue;"&gt;new&lt;/span&gt; test()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 22&lt;/span&gt; t.test 10&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 23&lt;/span&gt; System.GC.Collect(); System.GC.WaitForPendingFinalizers()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 24&lt;/span&gt; sw.Start()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 25&lt;/span&gt; t.test 10000000&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 26&lt;/span&gt; sw.Stop()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 27&lt;/span&gt; printf &lt;span style="color:maroon;"&gt;&amp;quot;%d&amp;quot;&lt;/span&gt; sw.ElapsedMilliseconds&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;“stejná věc” v C# (tak jak ji zkompiluje F#):&lt;/p&gt;

&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;namespace&lt;/span&gt; Test&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Program&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;abstract&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;FastFunc&lt;/span&gt;&amp;lt;T,U&amp;gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;abstract&lt;/span&gt; U Invoke(T t);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; V InvokeFast2&amp;lt;V&amp;gt;(&lt;span style="color:#2b91af;"&gt;FastFunc&lt;/span&gt;&amp;lt;T, &lt;span style="color:#2b91af;"&gt;FastFunc&lt;/span&gt;&amp;lt;U, V&amp;gt;&amp;gt; f, T t, U u)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;var&lt;/span&gt; func = f &lt;span style="color:blue;"&gt;as&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;FastFunc2&lt;/span&gt;&amp;lt;T, U, V&amp;gt;;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (func != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;return&lt;/span&gt; func.Invoke(t, u);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;return&lt;/span&gt; f.Invoke(t).Invoke(u);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 19&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 20&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 21&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;abstract&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;FastFunc2&lt;/span&gt;&amp;lt;T,U,V&amp;gt;:&lt;span style="color:#2b91af;"&gt;FastFunc&lt;/span&gt;&amp;lt;T, &lt;span style="color:#2b91af;"&gt;FastFunc&lt;/span&gt;&amp;lt;U, V&amp;gt;&amp;gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 22&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 23&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Closure&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;FastFunc&lt;/span&gt;&amp;lt;U, V&amp;gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 24&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 25&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;internal&lt;/span&gt; Closure(&lt;span style="color:#2b91af;"&gt;FastFunc2&lt;/span&gt;&amp;lt;T, U, V&amp;gt; f, T t)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 26&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 27&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _t = t;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 28&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _f = f;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 29&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 30&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;override&lt;/span&gt; V Invoke(U u)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 31&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 32&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;return&lt;/span&gt; _f.Invoke(_t, u);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 33&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 34&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;readonly&lt;/span&gt; T _t;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 35&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;readonly&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;FastFunc2&lt;/span&gt;&amp;lt;T, U, V&amp;gt; _f;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 36&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 37&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;override&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;FastFunc&lt;/span&gt;&amp;lt;U, V&amp;gt; Invoke(T t)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 38&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 39&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Closure&lt;/span&gt;(&lt;span style="color:blue;"&gt;this&lt;/span&gt;,t);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 40&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 41&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;abstract&lt;/span&gt; V Invoke(T t, U u);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 42&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 43&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 44&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;AddBinOp&lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;FastFunc2&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;,&lt;span style="color:blue;"&gt;int&lt;/span&gt;,&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 45&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 46&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;override&lt;/span&gt; &lt;span style="color:blue;"&gt;int&lt;/span&gt; Invoke(&lt;span style="color:blue;"&gt;int&lt;/span&gt; x, &lt;span style="color:blue;"&gt;int&lt;/span&gt; y)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 47&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 48&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;return&lt;/span&gt; x + y;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 49&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 50&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 51&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SubBinOp&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;FastFunc2&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 52&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 53&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;override&lt;/span&gt; &lt;span style="color:blue;"&gt;int&lt;/span&gt; Invoke(&lt;span style="color:blue;"&gt;int&lt;/span&gt; x, &lt;span style="color:blue;"&gt;int&lt;/span&gt; y)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 54&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 55&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;return&lt;/span&gt; x - y;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 56&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 57&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 58&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Test&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 59&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 60&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;FastFunc2&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; op = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;AddBinOp&lt;/span&gt;();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 61&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;readonly&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;FastFunc2&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; opadd = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;AddBinOp&lt;/span&gt;();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 62&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;readonly&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;FastFunc2&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; opsub = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SubBinOp&lt;/span&gt;();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 63&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 64&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;void&lt;/span&gt; testiter(&lt;span style="color:blue;"&gt;int&lt;/span&gt; i)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 65&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 66&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;FastFunc&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;.InvokeFast2(op, i, i);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 67&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op = opsub;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 68&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;FastFunc&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;.InvokeFast2(op, i, i);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 69&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op = opadd;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 70&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 71&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 72&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; dotest(&lt;span style="color:blue;"&gt;int&lt;/span&gt; max)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 73&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 74&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;for&lt;/span&gt;(&lt;span style="color:blue;"&gt;int&lt;/span&gt; i=0;i&amp;lt;max;i++) testiter(i);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 75&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 76&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 77&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 78&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 79&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 80&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;var&lt;/span&gt; sw = &lt;span style="color:blue;"&gt;new&lt;/span&gt; System.Diagnostics.&lt;span style="color:#2b91af;"&gt;Stopwatch&lt;/span&gt;();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 81&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;var&lt;/span&gt; t=&lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Test&lt;/span&gt;();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 82&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; t.dotest(10);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 83&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;GC&lt;/span&gt;.Collect(); &lt;span style="color:#2b91af;"&gt;GC&lt;/span&gt;.WaitForPendingFinalizers();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 84&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; sw.Start();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 85&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; t.dotest(10000000);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 86&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; sw.Stop();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 87&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.Write(sw.ElapsedMilliseconds);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 88&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 89&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 90&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Řádky 23 až 36 jsou tam jen pro úplnost, nikdy se v tomto testu nespustí.&lt;/p&gt;

&lt;p&gt;No jo, ale v F# to trvá 609ms a v C# jen 184ms. Takže je jasné, že přetypováním (jak jsem si myslel v prvním díle) to není. Po prohlídnutí ILka, jsem zase uviděl tailcall (v C# zobrazení v Reflektoru totiž normální call od tailcallu nepoznáte). Ale k otestování samotné “—optimize notailcalls” nepomůže, protože FastFunc2 je implementovaná v FSharp.Core, takže ještě přidáme již zmíněný “—standalone” a výsledek je 189ms, rozdíl od C# se mi v assembleru už hledat nechce, ILko vypadá v podstatě shodně. Mimochodem to “—standalone” tam opravdu napere celou FSharp.Core i to co se nepoužívá (kompilace najednou trvá již znatelných 5s).&lt;/p&gt;

&lt;p&gt;Pokud tedy v .Net 4.0 nebude tailcall optimalizovaný tak jak má, tak to funkcionální jazyky jako F# dost penalizuje a tak ztrácí mé cenné body :-).&lt;/p&gt;

&lt;p&gt;Ještě taková perlička na závěr. Mono je známé tím, že tailcall zatím ignoruje. Tím ovšem je pro funkcionální jazyky, stejně jako Java, téměř nepoužitelné. Po přeměření v Monu 2.4 to co trvalo na .Netu (F#) 609ms trvá “jen” 361ms. To co v .Netu (C#) trvalo 184ms, tak v Monu 387ms.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Přidej do&lt;/strong&gt; &lt;a href = "http://linkuj.cz/?id=linkuj&amp;amp;url=http://blog.vyvojar.cz/bobris/archive/2009/04/14/ukazatel-na-funkci-3.aspx&amp;amp;;title=Ukazatel+na+funkci+3" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/14/ukazatel-na-funkci-3.aspx"&gt;linkuj.cz!&lt;/a&gt; |  &lt;a href = "http://www.jagg.cz/bookmarks.php?action=add&amp;amp;address=http://blog.vyvojar.cz/bobris/archive/2009/04/14/ukazatel-na-funkci-3.aspx&amp;amp;;title=Ukazatel+na+funkci+3" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/14/ukazatel-na-funkci-3.aspx"&gt;jagg.cz!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://blog.vyvojar.cz/bobris/archive/2009/04/14/ukazatel-na-funkci-3.aspx&amp;amp;;title=Ukazatel+na+funkci+3" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/14/ukazatel-na-funkci-3.aspx"&gt;del.icio.us!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/04/14/ukazatel-na-funkci-3.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/14/ukazatel-na-funkci-3.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/04/14/ukazatel-na-funkci-3.aspx&amp;amp;title=Ukazatel+na+funkci+3" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/14/ukazatel-na-funkci-3.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://blog.vyvojar.cz/bobris/archive/2009/04/14/ukazatel-na-funkci-3.aspx&amp;amp;;title=Ukazatel+na+funkci+3" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/14/ukazatel-na-funkci-3.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://blog.vyvojar.cz/bobris/archive/2009/04/14/ukazatel-na-funkci-3.aspx&amp;amp;;title=Ukazatel+na+funkci+3&amp;amp;;top=1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/14/ukazatel-na-funkci-3.aspx"&gt;live it!&lt;/a&gt; |  &lt;a href = "mailto:?body=Thought you might like this: http://blog.vyvojar.cz/bobris/archive/2009/04/14/ukazatel-na-funkci-3.aspx&amp;amp;;subject=Ukazatel+na+funkci+3" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/14/ukazatel-na-funkci-3.aspx"&gt;email it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blog.vyvojar.cz/aggbug.aspx?PostID=229373" width="1" height="1"&gt;</description><category domain="http://blog.vyvojar.cz/bobris/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blog.vyvojar.cz/bobris/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Ukazatel na funkci 2</title><link>http://blog.vyvojar.cz/bobris/archive/2009/04/11/ukazatel-na-funkci-2.aspx</link><pubDate>Fri, 10 Apr 2009 22:26:05 GMT</pubDate><guid isPermaLink="false">99a92ff2-698a-48c2-8eaf-f3d9b6202627:229354</guid><dc:creator>bobris</dc:creator><slash:comments>2</slash:comments><comments>http://blog.vyvojar.cz/bobris/comments/229354.aspx</comments><wfw:commentRss>http://blog.vyvojar.cz/bobris/commentrss.aspx?PostID=229354</wfw:commentRss><wfw:comment>http://blog.vyvojar.cz/bobris/rsscomments.aspx?PostID=229354</wfw:comment><description>&lt;p&gt;Pokračování z minula … (pokud jste ještě nečetli první část, tak tohle ani nemá moc cenu číst)&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Takže delegát volání vypadá takto:&lt;/p&gt;  &lt;p&gt;originál v C#: op(i,i);&amp;#160;&amp;#160;&amp;#160;&amp;#160; op je delegát&lt;/p&gt;  &lt;p&gt;0000002c&amp;#160; push&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; esi // v esi je naše “i” druhý parametr se již nevejde do registrů proto jde na zásobník    &lt;br /&gt;0000002d&amp;#160; mov&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ecx,dword ptr ds:[022F1EE8h]&amp;#160; // nahraje ze static proměnné (globální, proto na ds (datovém) segmentu) ukazatel na delegáta     &lt;br /&gt;00000033&amp;#160; mov&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; edx,esi&amp;#160; // máme první parametr nastavíme taky na “i”     &lt;br /&gt;00000035&amp;#160; mov&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; eax,dword ptr [ecx+0Ch]&amp;#160; // načteme ukazatel na kód samotné funkce     &lt;br /&gt;00000038&amp;#160; mov&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ecx,dword ptr [ecx+4]&amp;#160; // načteme “this” volaného objektu (my ho nepotřebujeme ale to volání degáta neví)     &lt;br /&gt;0000003b&amp;#160; call&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; eax // a samotné volání&lt;/p&gt;  &lt;p&gt;Takhle velmi podobně vypadá volaní virtuální funkce v C++ v případě jednoduché dědičnosti.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;V případě volání virtuální funkce na interface v .Netu to vypadá takto (v C# op.DoIt(i,i);): op je interface&lt;/p&gt;  &lt;p&gt;00000006&amp;#160; push&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; esi&amp;#160; // stejně jako u delegáta    &lt;br /&gt;00000007&amp;#160; mov&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ecx,dword ptr ds:[022F84B8h] // naše this     &lt;br /&gt;0000000d&amp;#160; mov&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; edx,esi&amp;#160; // první parametr jako u delegáta     &lt;br /&gt;0000000f&amp;#160; call&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; dword ptr ds:[00990210h] // magické volání které se snaží být rychlé&lt;/p&gt;  &lt;p&gt;V samotném VS pokud dáte StepInto tak jste rovnou v naší funkci. Bohužel to nemůže být pravda, to by ani obecně nefungovalo a bylo by to výrazně rychlejší než případ s delegátem. Takže pustíme WinDbg a zjistíme, že to skáče na takovýto kód (tento kód se tam objeví až po pár iteracích):&lt;/p&gt;  &lt;p&gt;00997012 cmp&amp;#160;&amp;#160;&amp;#160;&amp;#160; dword ptr [ecx],983D48h // test na typ objektu    &lt;br /&gt;00997018 jne&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0099a011 // tohle nikdy neskočí protože v tom konkrétním řádku vždy voláme stejnou virtuální metodu    &lt;br /&gt;0099701e jmp&amp;#160;&amp;#160;&amp;#160;&amp;#160; 00cd01e8 // přímo skok na implementaci naší sčítací nebo odčítací funkce&lt;/p&gt;  &lt;p&gt;V tomto případě máme tedy .Netnetem dynamicky generovaný “optimalizovaný” kód. Což mě přivedlo na myšlenku jak to ještě zrychlit:&lt;/p&gt;  &lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;   &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt; [&amp;lt;AbstractClass&amp;gt;]&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; BinOp() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;abstract&lt;/span&gt; &lt;span style="color:blue;"&gt;member&lt;/span&gt; run : int * int &lt;span style="color:blue;"&gt;-&amp;gt;&lt;/span&gt; int&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; AddBinOp() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;inherit&lt;/span&gt; BinOp()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;override&lt;/span&gt; this.run(x,y) = x+y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; SubBinOp() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;inherit&lt;/span&gt; BinOp()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;override&lt;/span&gt; this.run(x,y) = x-y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; test() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; &lt;span style="color:blue;"&gt;mutable&lt;/span&gt; op = &lt;span style="color:blue;"&gt;new&lt;/span&gt; AddBinOp() :&amp;gt; BinOp&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; opadd = &lt;span style="color:blue;"&gt;new&lt;/span&gt; AddBinOp() :&amp;gt; BinOp&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; opsub = &lt;span style="color:blue;"&gt;new&lt;/span&gt; SubBinOp() :&amp;gt; BinOp&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 19&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; testiter i=&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 20&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op.run(i,i)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 21&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- opsub&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 22&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op.run(i,i)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 23&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- opadd&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Výsledek 124ms. Takže je to přece jen rychlejší než delegáti (130ms). To samé v C# je 110ms. No a ještě z assembleru je vidět, že to přiřazení “op &amp;lt;- opadd” není jen obyčejná kopie ukazatele. To je kvůli garbage collectoru, musí se nějak dozvědět o všech změnách globálních proměnných typu ukazatel. Takže když ještě smažeme static:&lt;/p&gt;

&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;#light&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;open&lt;/span&gt; System&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt; [&amp;lt;AbstractClass&amp;gt;]&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; BinOp() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;abstract&lt;/span&gt; &lt;span style="color:blue;"&gt;member&lt;/span&gt; run : int * int &lt;span style="color:blue;"&gt;-&amp;gt;&lt;/span&gt; int&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; AddBinOp() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;inherit&lt;/span&gt; BinOp()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;override&lt;/span&gt; this.run(x,y) = x+y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; SubBinOp() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;inherit&lt;/span&gt; BinOp()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;override&lt;/span&gt; this.run(x,y) = x-y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; test() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; &lt;span style="color:blue;"&gt;mutable&lt;/span&gt; op = &lt;span style="color:blue;"&gt;new&lt;/span&gt; AddBinOp() :&amp;gt; BinOp&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; opadd = &lt;span style="color:blue;"&gt;new&lt;/span&gt; AddBinOp() :&amp;gt; BinOp&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; opsub = &lt;span style="color:blue;"&gt;new&lt;/span&gt; SubBinOp() :&amp;gt; BinOp&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 19&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; testiter i=&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 20&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op.run(i,i)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 21&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- opsub&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 22&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op.run(i,i)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 23&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- opadd&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 24&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 25&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;member&lt;/span&gt; &lt;span style="color:blue;"&gt;public&lt;/span&gt; this.test max =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 26&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;for&lt;/span&gt; i &lt;span style="color:blue;"&gt;in&lt;/span&gt; 0..max-1 &lt;span style="color:blue;"&gt;do&lt;/span&gt; testiter i&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 27&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 28&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;let&lt;/span&gt; sw = &lt;span style="color:blue;"&gt;new&lt;/span&gt; Diagnostics.Stopwatch()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 29&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;let&lt;/span&gt; t=&lt;span style="color:blue;"&gt;new&lt;/span&gt; test()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 30&lt;/span&gt; t.test 10&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 31&lt;/span&gt; System.GC.Collect(); System.GC.WaitForPendingFinalizers()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 32&lt;/span&gt; sw.Start()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 33&lt;/span&gt; t.test 10000000&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 34&lt;/span&gt; sw.Stop()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 35&lt;/span&gt; printf &lt;span style="color:maroon;"&gt;&amp;quot;%d&amp;quot;&lt;/span&gt; sw.ElapsedMilliseconds&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Dostáváme se na 104ms (v C# to již je stejně rychlé). To je více než desetkrát rychlejší než první test. A to je myslím už nejlepší čas jakého jde dosáhnout při zachování myšlenky testu.&lt;/p&gt;

&lt;p&gt;Když bych to shrnul:&lt;/p&gt;

&lt;p&gt;1) Rychlosti volání metod od nejrychlejšího jsou: nevirtuální metoda; virtuální metoda objektu; delegát na členskou metodu; delegát na statickou metodu; virtuální metoda interfacu. Pořadí posledních dvou možností závisí ještě na počtu a typu parametrů.&lt;/p&gt;

&lt;p&gt;2) Předpočítejte co se dá (i když to vypadá nevinně)&lt;/p&gt;

&lt;p&gt;3) Časté ukládání do statických/globálních ukazatelů je pomalé – raději se tomu vyhnout&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;PS: Pokud bylo něco nesrozumitelného nebo máte nějaký požadavek jít někde ještě více do hloubky tak se neostýchejte a napište mi to do komentářů.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Přidej do&lt;/strong&gt; &lt;a href = "http://linkuj.cz/?id=linkuj&amp;amp;url=http://blog.vyvojar.cz/bobris/archive/2009/04/11/ukazatel-na-funkci-2.aspx&amp;amp;;title=Ukazatel+na+funkci+2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/11/ukazatel-na-funkci-2.aspx"&gt;linkuj.cz!&lt;/a&gt; |  &lt;a href = "http://www.jagg.cz/bookmarks.php?action=add&amp;amp;address=http://blog.vyvojar.cz/bobris/archive/2009/04/11/ukazatel-na-funkci-2.aspx&amp;amp;;title=Ukazatel+na+funkci+2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/11/ukazatel-na-funkci-2.aspx"&gt;jagg.cz!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://blog.vyvojar.cz/bobris/archive/2009/04/11/ukazatel-na-funkci-2.aspx&amp;amp;;title=Ukazatel+na+funkci+2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/11/ukazatel-na-funkci-2.aspx"&gt;del.icio.us!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/04/11/ukazatel-na-funkci-2.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/11/ukazatel-na-funkci-2.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/04/11/ukazatel-na-funkci-2.aspx&amp;amp;title=Ukazatel+na+funkci+2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/11/ukazatel-na-funkci-2.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://blog.vyvojar.cz/bobris/archive/2009/04/11/ukazatel-na-funkci-2.aspx&amp;amp;;title=Ukazatel+na+funkci+2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/11/ukazatel-na-funkci-2.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://blog.vyvojar.cz/bobris/archive/2009/04/11/ukazatel-na-funkci-2.aspx&amp;amp;;title=Ukazatel+na+funkci+2&amp;amp;;top=1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/11/ukazatel-na-funkci-2.aspx"&gt;live it!&lt;/a&gt; |  &lt;a href = "mailto:?body=Thought you might like this: http://blog.vyvojar.cz/bobris/archive/2009/04/11/ukazatel-na-funkci-2.aspx&amp;amp;;subject=Ukazatel+na+funkci+2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/11/ukazatel-na-funkci-2.aspx"&gt;email it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blog.vyvojar.cz/aggbug.aspx?PostID=229354" width="1" height="1"&gt;</description><category domain="http://blog.vyvojar.cz/bobris/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blog.vyvojar.cz/bobris/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Ukazatel na funkci</title><link>http://blog.vyvojar.cz/bobris/archive/2009/04/09/ukazatel-na-funkci.aspx</link><pubDate>Wed, 08 Apr 2009 22:50:42 GMT</pubDate><guid isPermaLink="false">99a92ff2-698a-48c2-8eaf-f3d9b6202627:229309</guid><dc:creator>bobris</dc:creator><slash:comments>0</slash:comments><comments>http://blog.vyvojar.cz/bobris/comments/229309.aspx</comments><wfw:commentRss>http://blog.vyvojar.cz/bobris/commentrss.aspx?PostID=229309</wfw:commentRss><wfw:comment>http://blog.vyvojar.cz/bobris/rsscomments.aspx?PostID=229309</wfw:comment><description>&lt;p&gt;No nejdříve jsem si myslel, že budu psát rant na způsob jak jsou delegáti pomalejší oproti F# FastFunc, vždyť to má přece v názvu že má být rychlá, tak proč by to nemělo vyjít :-). Bohužel jsem nějak začal s následujícím mikrobenchmarkem:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;   &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;#light&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;open&lt;/span&gt; System&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; test() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; add x y = x+y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; sub x y = x-y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; &lt;span style="color:blue;"&gt;mutable&lt;/span&gt; op = add&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; testiter i=&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op i i |&amp;gt; ignore&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- sub&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op i i |&amp;gt; ignore&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- add&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;member&lt;/span&gt; &lt;span style="color:blue;"&gt;public&lt;/span&gt; test max =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;for&lt;/span&gt; i &lt;span style="color:blue;"&gt;in&lt;/span&gt; 0..max-1 &lt;span style="color:blue;"&gt;do&lt;/span&gt; testiter i&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;let&lt;/span&gt; sw = &lt;span style="color:blue;"&gt;new&lt;/span&gt; Diagnostics.Stopwatch()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 19&lt;/span&gt; test.test 10&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 20&lt;/span&gt; System.GC.Collect(); System.GC.WaitForPendingFinalizers()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 21&lt;/span&gt; sw.Start()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 22&lt;/span&gt; test.test 10000000&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 23&lt;/span&gt; sw.Stop()&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 24&lt;/span&gt; printf &lt;span style="color:maroon;"&gt;&amp;quot;%d&amp;quot;&lt;/span&gt; sw.ElapsedMilliseconds&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Řádky 15 a dál již nebudu opakovat, budou státe ty stejné a nezajímavé. Když se podíváte na vygenerovaný kód Reflektorem, určitě budete chvíli koukat kolikrát se tam ta operace (+) objeví, ač řádky 7 a 13 přiřazují to samé tak jsou pro to vytvořeny 2 naprosto stejné objekty, toto se ale doufám určitě v dalších verzích kompilátoru vylepší. Ale proč to vlastně nejsou delegáti .Netí ukazatel na funkci, proč to jsou nějaké objekty. To si nejdříve uděláme vysvětlující odbočku z funkcionálních jazyků.&lt;/p&gt;

&lt;p&gt;V F# kód “let add x y = x+y” definuje funkci add s tímto typem “int –&amp;gt; int –&amp;gt; int”, již z tohoto je jasné, že není všechno tak jak jsme zvyklí. Je to funkce s jedním int parametrem, která vrací funkci o jednom parametru a návratové hodnotě typu int. Takže je to taková funkce generující funkci. V .Netu pak to je typ: FastFunc&amp;lt;int, FastFunc&amp;lt;int, int&amp;gt;&amp;gt;. FastFunc je typ nadefinovaný v F# runtime knihovně FSharp.Core.dll (pokud chcete jen jedno exe můžete použít parameter –standalone u kompilátoru). FastFunc má pak abstraktní funkci U Invoke&amp;lt;T,U&amp;gt;(T a). Takže volání “op i i” by znamenalo vytvoření dočasného přičítače i a na ten teprve zavolat Invoke(i). Autoři F# to tedy vyřešili typem FastFunc2&amp;lt;int,int,int&amp;gt; funkci s dvěma parametry. Ta má již V Invoke(T,U) a taky genericky implementovanou FastFunc&amp;lt;U,V&amp;gt; Invoke(T). Samotné volání “op i i” pak je přeloženo jako volání statické funkce která nejdříve otestuje jestli to není FastFunc2 a rovnou jí zavolá, bez vytváření dočasného objektu. Tato optimalizace ovšem nejde pomocí delegátů implementovat delegát nemůže mít zároveň 2 typy Func&amp;lt;int,Func&amp;lt;int,int&amp;gt;&amp;gt; a Func&amp;lt;int,int,int&amp;gt; a to ho prvního se “funkcionalisté” vzdát nemohou.&lt;/p&gt;

&lt;p&gt;Výsledný čas na mém počítači je pak 1200ms.&lt;/p&gt;

&lt;p&gt;Můžeme to, ale zkusit F# ulehčit takto:&lt;/p&gt;

&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; test() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; add (x,y) = x+y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; sub (x,y) = x-y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; &lt;span style="color:blue;"&gt;mutable&lt;/span&gt; op = add&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; testiter i=&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op (i,i) |&amp;gt; ignore&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- sub&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op (i,i) |&amp;gt; ignore&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- add&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Dokonce to vypadá i podobněji jako C# :-). No jo jenže jen vypadá. Zápis “(x,y)” je definice “tuple”, takže nově má add tuto definici (int * int) –&amp;gt; int. Je to již funkce o jednom! parametru. Nejdřive jsem se podíval na výsledek do Reflektoru mráz mě polil je to “class &lt;b&gt;Tuple&lt;/b&gt;&amp;lt;&lt;b&gt;A&lt;/b&gt;, &lt;b&gt;B&lt;/b&gt;&amp;gt;” ano class, takže při každém volání se alokuje (int &lt;b&gt;num&lt;/b&gt; = op@7.Invoke(new Tuple&amp;lt;int, int&amp;gt;(i, i));). To jsem si tedy moc nepomohl jsem si říkal, jak může být alokace rychlejší než podmínka na typ a přetypování. Výsledek překvapil: 880 ms&lt;/p&gt;

&lt;p&gt;Ovšem i řádek 11 a 13 jsou alokace, taky je zkusíme eliminovat:&lt;/p&gt;

&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; test() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; add (x,y) = x+y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; sub (x,y) = x-y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; &lt;span style="color:blue;"&gt;mutable&lt;/span&gt; op = add&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; opadd = add&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; opsub = sub&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; testiter i=&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op (i,i) |&amp;gt; ignore&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- opsub&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op (i,i) |&amp;gt; ignore&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- opadd&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Výsledek 710ms - lepší. Pokud se stejně předalokuje původní kód tak to dělá 1100ms.&lt;/p&gt;

&lt;p&gt;Zkusíme tedy pomoci F# znovu, použijeme delegáty:&lt;/p&gt;

&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; IntBinaryOp = &lt;span style="color:blue;"&gt;delegate&lt;/span&gt; &lt;span style="color:blue;"&gt;of&lt;/span&gt; int * int &lt;span style="color:blue;"&gt;-&amp;gt;&lt;/span&gt; int&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; test() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; add x y = x+y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; sub x y = x-y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; &lt;span style="color:blue;"&gt;mutable&lt;/span&gt; op = &lt;span style="color:blue;"&gt;new&lt;/span&gt; IntBinaryOp(add)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; testiter i=&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op.Invoke(i,i) |&amp;gt; ignore&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- &lt;span style="color:blue;"&gt;new&lt;/span&gt; IntBinaryOp(sub)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op.Invoke(i,i) |&amp;gt; ignore&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- &lt;span style="color:blue;"&gt;new&lt;/span&gt; IntBinaryOp(add)&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Ze začatku výsledek 1080ms nevypadá vůbec nadějně. Do té doby než zjistíme, že řádek 13 má v F# v sobě zbytečně 2 alokace:&lt;/p&gt;

&lt;p&gt;op@9 = new Program.IntBinaryOp(new Program.testiter@13@15().Invoke);&lt;/p&gt;

&lt;p&gt;První je delegát, jasně to tam být musí, ale to druhé je object bez memberů který jen volá statickou metodu sub, naprostá zbytečnost. Trošku jako by delegáti byli “2nd class” obyvatelé v F# a není jim věnováno tolik pozornosti kolik by si možná zasloužili, ale je jasný, že to není problém vylepšit v C# to samé je ok. Ok provedeme předalokování:&lt;/p&gt;

&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; IntBinaryOp = &lt;span style="color:blue;"&gt;delegate&lt;/span&gt; &lt;span style="color:blue;"&gt;of&lt;/span&gt; int * int &lt;span style="color:blue;"&gt;-&amp;gt;&lt;/span&gt; int&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; test() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; add x y = x+y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; sub x y = x-y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; &lt;span style="color:blue;"&gt;mutable&lt;/span&gt; op = &lt;span style="color:blue;"&gt;new&lt;/span&gt; IntBinaryOp(add)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; opadd = &lt;span style="color:blue;"&gt;new&lt;/span&gt; IntBinaryOp(add)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; opsub = &lt;span style="color:blue;"&gt;new&lt;/span&gt; IntBinaryOp(sub)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; testiter i=&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op.Invoke(i,i) |&amp;gt; ignore&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- opsub&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op.Invoke(i,i) |&amp;gt; ignore&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- opadd&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 19&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;member&lt;/span&gt; &lt;span style="color:blue;"&gt;public&lt;/span&gt; test max =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 20&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;for&lt;/span&gt; i &lt;span style="color:blue;"&gt;in&lt;/span&gt; 0..max-1 &lt;span style="color:blue;"&gt;do&lt;/span&gt; testiter i&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Výsledek mě nepotěšil 570ms. Proč nepotěšil, vždyť je to nejlepší výsledek, jenže já už znal výsledek C# ze stejného kódu:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;namespace&lt;/span&gt; Test&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Program&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Test&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;int&lt;/span&gt; add(&lt;span style="color:blue;"&gt;int&lt;/span&gt; x, &lt;span style="color:blue;"&gt;int&lt;/span&gt; y)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;return&lt;/span&gt; x + y;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;int&lt;/span&gt; sub(&lt;span style="color:blue;"&gt;int&lt;/span&gt; x, &lt;span style="color:blue;"&gt;int&lt;/span&gt; y)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;return&lt;/span&gt; x + y;&amp;#160;&amp;#160; &lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; op = add;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 19&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; opadd = add;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 20&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; opsub = sub;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 21&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 22&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; testiter(&lt;span style="color:blue;"&gt;int&lt;/span&gt; i)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 23&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 24&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op(i, i);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 25&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op = opsub;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 26&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op(i, i);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 27&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op = opadd;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 28&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 29&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 30&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; dotest(&lt;span style="color:blue;"&gt;int&lt;/span&gt; max)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 31&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 32&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;for&lt;/span&gt;(&lt;span style="color:blue;"&gt;int&lt;/span&gt; i=0;i&amp;lt;max;i++) testiter(i);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 33&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 34&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 35&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 36&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] aArgs)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 37&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 38&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;var&lt;/span&gt; sw = &lt;span style="color:blue;"&gt;new&lt;/span&gt; System.Diagnostics.&lt;span style="color:#2b91af;"&gt;Stopwatch&lt;/span&gt;();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 39&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Test&lt;/span&gt;.dotest(10);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 40&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;GC&lt;/span&gt;.Collect(); &lt;span style="color:#2b91af;"&gt;GC&lt;/span&gt;.WaitForPendingFinalizers();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 41&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; sw.Start();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 42&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Test&lt;/span&gt;.dotest(10000000);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 43&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; sw.Stop();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 44&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.Write(sw.ElapsedMilliseconds);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 45&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 46&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 47&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;155 ms! Výsledný kód je až na to jedno volání v F# navíc stejný, navíc u takhle krátkých metod by mohl .Net bez problémů inlinovat. Dobře né úplně bez problémů jak si ukážeme v zápětí, ta funkce totiž vypadá v ILku takto:&lt;/p&gt;

&lt;p&gt;.method assembly instance int32 Invoke(int32, int32) cil managed
  &lt;br /&gt;{

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .maxstack 6

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; L_0000: ldarg.1 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; L_0001: ldarg.2 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; L_0002: tail 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; L_0004: call int32 Program/test::add@7(int32, int32)

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; L_0009: ret 

  &lt;br /&gt;}&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Už tušíte je tam tall call a ne obyčejný call. Dobře ověříme si to pomocí parametru --optimize- notailcalls je vypneme výsledek je tento:&lt;/p&gt;

&lt;p&gt;.method assembly instance int32 Invoke(int32, int32) cil managed
  &lt;br /&gt;{

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .maxstack 6

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .locals init (

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [0] int32 num,

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [1] int32 num2)

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; L_0000: ldarg.1 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; L_0001: stloc.0 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; L_0002: ldarg.2 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; L_0003: stloc.1 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; L_0004: ldloc.0 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; L_0005: ldloc.1 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; L_0006: call int32 Program/test::add@7(int32, int32)

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; L_000b: ret 

  &lt;br /&gt;}&lt;/p&gt;

&lt;p&gt;A čas 140 ms! ano zdá se, že .Net tailcall neinlinuje, ale navíc s tím musí mít ještě nějaký problém rozdíl je příliš velký. No ale proč je to tedy, ale teď rychlejší než C#. Ano to je již známý problém volání static funkce pomocí delegáta a nutnosti posunout parametry v registrech kvůli neexistujícímu this ve statické metodě. Opravíme tedy náš C# kód takto:&lt;/p&gt;

&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;int&lt;/span&gt; add(&lt;span style="color:blue;"&gt;int&lt;/span&gt; x, &lt;span style="color:blue;"&gt;int&lt;/span&gt; y)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;return&lt;/span&gt; x + y;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;int&lt;/span&gt; sub(&lt;span style="color:blue;"&gt;int&lt;/span&gt; x, &lt;span style="color:blue;"&gt;int&lt;/span&gt; y)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;return&lt;/span&gt; x + y;&amp;#160;&amp;#160; &lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; op = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Test&lt;/span&gt;().add;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 19&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; opadd = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Test&lt;/span&gt;().add;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 20&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; opsub = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Test&lt;/span&gt;().sub;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;A výsledek je 126ms. Podobného výsledku dosáhneme v F# pokud napíšeme třeba takto (již je to ale trochu jiný benchmark opustili sme statické metody a dokonce i členské a navíc odstraníme i “|&amp;gt; ignore”, které to taky trochu né úplně logicky zpomaluje:&lt;/p&gt;

&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;let&lt;/span&gt; add x y = x+y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;let&lt;/span&gt; sub x y = x-y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; test() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; &lt;span style="color:blue;"&gt;mutable&lt;/span&gt; op = &lt;span style="color:blue;"&gt;new&lt;/span&gt; IntBinaryOp(add)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; opadd = &lt;span style="color:blue;"&gt;new&lt;/span&gt; IntBinaryOp(add)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; opsub = &lt;span style="color:blue;"&gt;new&lt;/span&gt; IntBinaryOp(sub)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; testiter i=&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op.Invoke(i,i)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- opsub&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op.Invoke(i,i)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- opadd&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Výsledek je 130ms. Nevím proč je to o 4ms pomalejší, žádný rozumný důvod pro rozdíl již v Reflektoru nevidím.&lt;/p&gt;

&lt;p&gt;Ještě si ukážeme “objektové” řešení v F#:&lt;/p&gt;

&lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;
  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; IBinOp =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;abstract&lt;/span&gt; &lt;span style="color:blue;"&gt;member&lt;/span&gt; run : int * int &lt;span style="color:blue;"&gt;-&amp;gt;&lt;/span&gt; int&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; AddBinOp() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;interface&lt;/span&gt; IBinOp &lt;span style="color:blue;"&gt;with&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;member&lt;/span&gt; this.run(x,y) = x+y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; SubBinOp() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;interface&lt;/span&gt; IBinOp &lt;span style="color:blue;"&gt;with&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;member&lt;/span&gt; this.run(x,y) = x-y&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;type&lt;/span&gt; test() =&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; &lt;span style="color:blue;"&gt;mutable&lt;/span&gt; op = &lt;span style="color:blue;"&gt;new&lt;/span&gt; AddBinOp() :&amp;gt; IBinOp&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; opadd = &lt;span style="color:blue;"&gt;new&lt;/span&gt; AddBinOp() :&amp;gt; IBinOp&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; opsub = &lt;span style="color:blue;"&gt;new&lt;/span&gt; SubBinOp() :&amp;gt; IBinOp&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;let&lt;/span&gt; testiter i=&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 19&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op.run(i,i)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 20&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- opsub&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 21&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op.run(i,i)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 22&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; op &amp;lt;- opadd&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Zajímavé je že běží 146ms. Takže z toho vyplívá, že rychlost volání delegáta je rychlejší než volání virtuální metody a to už je co říct …&lt;/p&gt;

&lt;p&gt;V závěru co z toho plyne: měřit, reflektorovat a znovu měřit a znovu reflektorovat a znát co váš kompilátor a platforma umí dobře a to preferovat. Na příště mi zbývá zjistit jak se liší virtualní metoda od delegáta v assembleru a jestě se podívám na to pomalé přetypovaní na FastFunc2 (být pomalejší než alokace to už chce hodně kumštu). Taky jsem zvědav na .Net 4.0, tam už mohli F#isti zatlačit, aby třeba tailcall byl lépe optimalizován, takže s .Net 4.0 se může vše změnit, nějaká beta běžící mimo virtualizaci by se hodila :).&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Přidej do&lt;/strong&gt; &lt;a href = "http://linkuj.cz/?id=linkuj&amp;amp;url=http://blog.vyvojar.cz/bobris/archive/2009/04/09/ukazatel-na-funkci.aspx&amp;amp;;title=Ukazatel+na+funkci" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/09/ukazatel-na-funkci.aspx"&gt;linkuj.cz!&lt;/a&gt; |  &lt;a href = "http://www.jagg.cz/bookmarks.php?action=add&amp;amp;address=http://blog.vyvojar.cz/bobris/archive/2009/04/09/ukazatel-na-funkci.aspx&amp;amp;;title=Ukazatel+na+funkci" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/09/ukazatel-na-funkci.aspx"&gt;jagg.cz!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://blog.vyvojar.cz/bobris/archive/2009/04/09/ukazatel-na-funkci.aspx&amp;amp;;title=Ukazatel+na+funkci" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/09/ukazatel-na-funkci.aspx"&gt;del.icio.us!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/04/09/ukazatel-na-funkci.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/09/ukazatel-na-funkci.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/04/09/ukazatel-na-funkci.aspx&amp;amp;title=Ukazatel+na+funkci" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/09/ukazatel-na-funkci.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://blog.vyvojar.cz/bobris/archive/2009/04/09/ukazatel-na-funkci.aspx&amp;amp;;title=Ukazatel+na+funkci" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/09/ukazatel-na-funkci.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://blog.vyvojar.cz/bobris/archive/2009/04/09/ukazatel-na-funkci.aspx&amp;amp;;title=Ukazatel+na+funkci&amp;amp;;top=1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/09/ukazatel-na-funkci.aspx"&gt;live it!&lt;/a&gt; |  &lt;a href = "mailto:?body=Thought you might like this: http://blog.vyvojar.cz/bobris/archive/2009/04/09/ukazatel-na-funkci.aspx&amp;amp;;subject=Ukazatel+na+funkci" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/04/09/ukazatel-na-funkci.aspx"&gt;email it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blog.vyvojar.cz/aggbug.aspx?PostID=229309" width="1" height="1"&gt;</description><category domain="http://blog.vyvojar.cz/bobris/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blog.vyvojar.cz/bobris/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Iterátory C# vs F#</title><link>http://blog.vyvojar.cz/bobris/archive/2009/03/12/iter-tory-c-vs-f.aspx</link><pubDate>Wed, 11 Mar 2009 23:30:00 GMT</pubDate><guid isPermaLink="false">99a92ff2-698a-48c2-8eaf-f3d9b6202627:229138</guid><dc:creator>bobris</dc:creator><slash:comments>4</slash:comments><comments>http://blog.vyvojar.cz/bobris/comments/229138.aspx</comments><wfw:commentRss>http://blog.vyvojar.cz/bobris/commentrss.aspx?PostID=229138</wfw:commentRss><wfw:comment>http://blog.vyvojar.cz/bobris/rsscomments.aspx?PostID=229138</wfw:comment><description>&lt;P&gt;Již jsem tu na blogu trochu kritizoval F# za nedostatečně optimální kód. Ted bych rád byl více konkrétní. Na pomoc jsem zavolal CLRProfiler. Napsal jsem dva “identické” programy. Nejdříve F# verzi:&lt;/P&gt;
&lt;DIV style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:courier new;"&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR:blue;"&gt;#light&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR:blue;"&gt;open&lt;/SPAN&gt; System&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR:blue;"&gt;open&lt;/SPAN&gt; System.IO&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR:blue;"&gt;let&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;mutable&lt;/SPAN&gt; fileCount = 0&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 6&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR:blue;"&gt;let&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;mutable&lt;/SPAN&gt; dirCount = 0&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 7&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR:blue;"&gt;let&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;rec&lt;/SPAN&gt; allFiles dir = &lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 9&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; seq {&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 10&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;for&lt;/SPAN&gt; file &lt;SPAN style="COLOR:blue;"&gt;in&lt;/SPAN&gt; Directory.GetFiles dir &lt;SPAN style="COLOR:blue;"&gt;do&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 11&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fileCount &amp;lt;- fileCount + 1&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 12&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;yield&lt;/SPAN&gt; file&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 13&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;for&lt;/SPAN&gt; subdir &lt;SPAN style="COLOR:blue;"&gt;in&lt;/SPAN&gt; Directory.GetDirectories dir &lt;SPAN style="COLOR:blue;"&gt;do&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 14&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dirCount &amp;lt;- dirCount + 1&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 15&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;yield!&lt;/SPAN&gt; (allFiles subdir) &lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 16&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 17&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 18&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR:blue;"&gt;for&lt;/SPAN&gt; i &lt;SPAN style="COLOR:blue;"&gt;in&lt;/SPAN&gt; allFiles &lt;SPAN style="COLOR:maroon;"&gt;@"C:\Windows\System32\"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;do&lt;/SPAN&gt; Console.WriteLine i&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 19&lt;/SPAN&gt; printf &lt;SPAN style="COLOR:maroon;"&gt;"Files: %d Dirs: %d"&lt;/SPAN&gt; fileCount dirCount&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Krátké, výstižné, nedebugovatelné (ale to počítám, že snad s dalšími verzemi F# vyřeší) …&lt;/P&gt;
&lt;P&gt;A pokračuje C# verze:&lt;/P&gt;
&lt;DIV style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:courier new;"&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR:blue;"&gt;using&lt;/SPAN&gt; System;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR:blue;"&gt;using&lt;/SPAN&gt; System.IO;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR:blue;"&gt;using&lt;/SPAN&gt; System.Collections.Generic;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR:blue;"&gt;namespace&lt;/SPAN&gt; Test&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 6&lt;/SPAN&gt; {&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 7&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;Program&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 9&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;int&lt;/SPAN&gt; fileCount = 0;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 10&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;int&lt;/SPAN&gt; dirCount = 0;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 11&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 12&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR:blue;"&gt;string&lt;/SPAN&gt;&amp;gt; allFiles(&lt;SPAN style="COLOR:blue;"&gt;string&lt;/SPAN&gt; aDir)&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 13&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 14&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;foreach&lt;/SPAN&gt; (&lt;SPAN style="COLOR:blue;"&gt;var&lt;/SPAN&gt; file &lt;SPAN style="COLOR:blue;"&gt;in&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;Directory&lt;/SPAN&gt;.GetFiles(aDir))&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 15&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 16&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fileCount++;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 17&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;yield&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; file;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 18&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 19&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;foreach&lt;/SPAN&gt; (&lt;SPAN style="COLOR:blue;"&gt;var&lt;/SPAN&gt; subdir &lt;SPAN style="COLOR:blue;"&gt;in&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;Directory&lt;/SPAN&gt;.GetDirectories(aDir))&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 20&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 21&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dirCount++;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 22&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;foreach&lt;/SPAN&gt; (&lt;SPAN style="COLOR:blue;"&gt;var&lt;/SPAN&gt; file &lt;SPAN style="COLOR:blue;"&gt;in&lt;/SPAN&gt; allFiles(subdir))&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 23&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 24&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;yield&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; file;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 25&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 26&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 27&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 28&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 29&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; Main(&lt;SPAN style="COLOR:blue;"&gt;string&lt;/SPAN&gt;[] aArgs)&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 30&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 31&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;foreach&lt;/SPAN&gt; (&lt;SPAN style="COLOR:blue;"&gt;var&lt;/SPAN&gt; i &lt;SPAN style="COLOR:blue;"&gt;in&lt;/SPAN&gt; allFiles(&lt;SPAN style="COLOR:#a31515;"&gt;@"C:\Windows\System32\"&lt;/SPAN&gt;)) &lt;SPAN style="COLOR:#2b91af;"&gt;Console&lt;/SPAN&gt;.WriteLine(i);&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 32&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:#2b91af;"&gt;Console&lt;/SPAN&gt;.WriteLine(&lt;SPAN style="COLOR:#a31515;"&gt;"Files: {0} Dirs: {1}"&lt;/SPAN&gt;, fileCount, dirCount);&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 33&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 34&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp; 35&lt;/SPAN&gt; }&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Delší (hlavně o závorky a chybějící “yield foreach”), ale taky myslím výstižné, bez problému debugovatelné.&lt;/P&gt;
&lt;P&gt;Na mém počítači vypíše poslední WriteLine toto: (samozřejmě obě verze mají naprosto stejný výstup)&lt;/P&gt;
&lt;P&gt;Files: 4924 Dirs: 243&lt;/P&gt;
&lt;P&gt;No a teď výsledky z CLRProfileru: (zakroužkoval jsem objekty co jsou “navíc”, povšimněte si taky velikosti scrollbaru)&lt;/P&gt;
&lt;P&gt;&lt;IMG style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;DISPLAY:inline;BORDER-RIGHT-WIDTH:0px;" title=IterFSharpvsCSharp border=0 alt=IterFSharpvsCSharp src="http://blog.vyvojar.cz/blogs/bobris/IterFSharpvsCSharp_3B6F9D58.png" width=938 height=913&gt; &lt;/P&gt;
&lt;P&gt;Takže už víte co jsem myslel tím větším tlakem na GC. V tomto konkrétním případě s relativně dlouhými řetězci, to dělá o 30% hůře pro F# (112% v počtu instancí!).&lt;/P&gt;
&lt;P&gt;PS: Vývojáři F#, ale mají u mne jedno malé plus za to, že #light režim bude výchozí nastavení. Začínám vidět výhody velmi kontroverzního Python like scope==indent :-) (Především vynucená disciplína alespoň nějakého vzhledu zdrojáků)&lt;/P&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Přidej do&lt;/strong&gt; &lt;a href = "http://linkuj.cz/?id=linkuj&amp;amp;url=http://blog.vyvojar.cz/bobris/archive/2009/03/12/iter-tory-c-vs-f.aspx&amp;amp;;title=Iter%26%23225%3btory+C%23+vs+F%23" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/03/12/iter-tory-c-vs-f.aspx"&gt;linkuj.cz!&lt;/a&gt; |  &lt;a href = "http://www.jagg.cz/bookmarks.php?action=add&amp;amp;address=http://blog.vyvojar.cz/bobris/archive/2009/03/12/iter-tory-c-vs-f.aspx&amp;amp;;title=Iter%26%23225%3btory+C%23+vs+F%23" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/03/12/iter-tory-c-vs-f.aspx"&gt;jagg.cz!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://blog.vyvojar.cz/bobris/archive/2009/03/12/iter-tory-c-vs-f.aspx&amp;amp;;title=Iter%26%23225%3btory+C%23+vs+F%23" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/03/12/iter-tory-c-vs-f.aspx"&gt;del.icio.us!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/03/12/iter-tory-c-vs-f.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/03/12/iter-tory-c-vs-f.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/03/12/iter-tory-c-vs-f.aspx&amp;amp;title=Iter%26%23225%3btory+C%23+vs+F%23" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/03/12/iter-tory-c-vs-f.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://blog.vyvojar.cz/bobris/archive/2009/03/12/iter-tory-c-vs-f.aspx&amp;amp;;title=Iter%26%23225%3btory+C%23+vs+F%23" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/03/12/iter-tory-c-vs-f.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://blog.vyvojar.cz/bobris/archive/2009/03/12/iter-tory-c-vs-f.aspx&amp;amp;;title=Iter%26%23225%3btory+C%23+vs+F%23&amp;amp;;top=1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/03/12/iter-tory-c-vs-f.aspx"&gt;live it!&lt;/a&gt; |  &lt;a href = "mailto:?body=Thought you might like this: http://blog.vyvojar.cz/bobris/archive/2009/03/12/iter-tory-c-vs-f.aspx&amp;amp;;subject=Iter%26%23225%3btory+C%23+vs+F%23" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/03/12/iter-tory-c-vs-f.aspx"&gt;email it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blog.vyvojar.cz/aggbug.aspx?PostID=229138" width="1" height="1"&gt;</description><category domain="http://blog.vyvojar.cz/bobris/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blog.vyvojar.cz/bobris/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Maestro a Monitor</title><link>http://blog.vyvojar.cz/bobris/archive/2009/03/02/maestro-a-monitor.aspx</link><pubDate>Sun, 01 Mar 2009 23:13:00 GMT</pubDate><guid isPermaLink="false">99a92ff2-698a-48c2-8eaf-f3d9b6202627:229077</guid><dc:creator>bobris</dc:creator><slash:comments>4</slash:comments><comments>http://blog.vyvojar.cz/bobris/comments/229077.aspx</comments><wfw:commentRss>http://blog.vyvojar.cz/bobris/commentrss.aspx?PostID=229077</wfw:commentRss><wfw:comment>http://blog.vyvojar.cz/bobris/rsscomments.aspx?PostID=229077</wfw:comment><description>&lt;p&gt;Maestro jazyk se nám začíná rozjíždět. Již má vlastní blog: &lt;a title="http://blogs.msdn.com/maestroteam" href="http://blogs.msdn.com/maestroteam"&gt;http://blogs.msdn.com/maestroteam&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Co se ale na blogu nepřímo (je to až v komentářích) dočtete je, že je to postavené nad “forknutým” a lehce modifikovaným &lt;a href="http://www.microsoft.com/ccrdss/"&gt;CCR&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Jinak doporučuji zhlédnout &lt;a title="http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Meijer-and-Chrysanthakopoulos-Concurrency-Coordination-and-the-CCR/" href="http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Meijer-and-Chrysanthakopoulos-Concurrency-Coordination-and-the-CCR/"&gt;http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Meijer-and-Chrysanthakopoulos-Concurrency-Coordination-and-the-CCR/&lt;/a&gt; – George je hodně zanícený o CCR (řecká povaha se nezapře)&lt;/p&gt;  &lt;p&gt;No a další video je pak &lt;a title="http://channel9.msdn.com/shows/Going+Deep/Joe-Duffy-Perspectives-on-Concurrent-Programming-and-Parallelism/" href="http://channel9.msdn.com/shows/Going+Deep/Joe-Duffy-Perspectives-on-Concurrent-Programming-and-Parallelism/"&gt;http://channel9.msdn.com/shows/Going+Deep/Joe-Duffy-Perspectives-on-Concurrent-Programming-and-Parallelism/&lt;/a&gt; – Joe Duffy je skinhead paralelismu :-), už se těším na jeho bichli Concurrent Programming on Windows, příjde na řadu hned jak dočtu Expert F# :-). Je tam rychle načrtnuto hodně různých věcí na kterých pracují, dokonce možnost forkovat BCL na paralelní (ve smyslu vývoje) anotovanou popisem vedlejších efektů knihovnu například používající “nové” delegáty deklarující, že jsou bez vedlejších efektů a tak …&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Druhá část ublognutí bude o komentáři od “pazu” cituji:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Osobně si myslím, že pokud se v kódu objevují ManualResetEvent a jiné &amp;quot;zamykací&amp;quot; mechanismy, nemá smysl věc komplikovat a stačí použít tradiční přístup - místo hypotetického superframeworku na vysoké abstraktní úrovni&amp;#160; radši problém vyřešit na mirkoúrovni Monitor&amp;amp;spol pro můj jeden konkrétní případ.&lt;/em&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Zrovna ManualResetEvent byl použit v &lt;a href="http://blog.vyvojar.cz/bobris/archive/2009/02/17/asynchronn-kop-rov-n-proud-st-2.aspx" target="_blank"&gt;komentovaném článku&lt;/a&gt; v tomto “vzoru”:&lt;/p&gt;  &lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;var&lt;/span&gt; ev = &lt;span style="color:blue;"&gt;new&lt;/span&gt; System.Threading.&lt;span style="color:#2b91af;"&gt;ManualResetEvent&lt;/span&gt;(&lt;span style="color:blue;"&gt;false&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt; System.Threading.&lt;span style="color:#2b91af;"&gt;ThreadPool&lt;/span&gt;.QueueUserWorkItem((o) =&amp;gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:green;"&gt;// Do something long&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ev.Set();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; });&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&lt;span style="color:green;"&gt;// Do something different&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt; ev.WaitOne();&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Pokud bych toto chtěl napsat pomocí Monitoru, tak mě nic jiného než toto nenapadá:&lt;/p&gt;  &lt;div style="font-size:10pt;background:white;color:black;font-family:courier new;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;var&lt;/span&gt; monitor = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Object&lt;/span&gt;();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;var&lt;/span&gt; done = &lt;span style="color:blue;"&gt;false&lt;/span&gt;;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt; System.Threading.&lt;span style="color:#2b91af;"&gt;ThreadPool&lt;/span&gt;.QueueUserWorkItem((o) =&amp;gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:green;"&gt;// Do something long&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Threading.&lt;span style="color:#2b91af;"&gt;Monitor&lt;/span&gt;.Enter(o);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; done = &lt;span style="color:blue;"&gt;true&lt;/span&gt;;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Threading.&lt;span style="color:#2b91af;"&gt;Monitor&lt;/span&gt;.Pulse(o);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Threading.&lt;span style="color:#2b91af;"&gt;Monitor&lt;/span&gt;.Exit(o);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }, monitor);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&lt;span style="color:green;"&gt;// Do something different&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt; System.Threading.&lt;span style="color:#2b91af;"&gt;Monitor&lt;/span&gt;.Enter(monitor);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (!done) System.Threading.&lt;span style="color:#2b91af;"&gt;Monitor&lt;/span&gt;.Wait(monitor);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt; System.Threading.&lt;span style="color:#2b91af;"&gt;Monitor&lt;/span&gt;.Exit(monitor);&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Proměnná “done” tam musí být, aby bylo ošetřeno pokud by “something different” trvalo déle než “something long” Navíc Monitor stejně musí opravdový Win32 Event vytvořit pokud čekání ve Waitu trvá déle jinak nelze udělat dlouhodobé čekání ve Windows, aby to bralo minimálně zdrojů.&lt;/p&gt;  &lt;p&gt;Takže i když pravděpodobně to bylo myšleno trochu jinak, rozhodně se není potřeba ManualResetEventu bát :-). Na druhou stranu je to ale debata bez budoucnosti, protože v .Net 4.0 PFX pak tento vzor vyřeší ještě optimálněji a kratčeji ještě než pomocí ManualResetEventu (v podstatě řádky 1 a 5 nebudou potřeba).&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Přidej do&lt;/strong&gt; &lt;a href = "http://linkuj.cz/?id=linkuj&amp;amp;url=http://blog.vyvojar.cz/bobris/archive/2009/03/02/maestro-a-monitor.aspx&amp;amp;;title=Maestro+a+Monitor" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/03/02/maestro-a-monitor.aspx"&gt;linkuj.cz!&lt;/a&gt; |  &lt;a href = "http://www.jagg.cz/bookmarks.php?action=add&amp;amp;address=http://blog.vyvojar.cz/bobris/archive/2009/03/02/maestro-a-monitor.aspx&amp;amp;;title=Maestro+a+Monitor" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/03/02/maestro-a-monitor.aspx"&gt;jagg.cz!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://blog.vyvojar.cz/bobris/archive/2009/03/02/maestro-a-monitor.aspx&amp;amp;;title=Maestro+a+Monitor" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/03/02/maestro-a-monitor.aspx"&gt;del.icio.us!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/03/02/maestro-a-monitor.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/03/02/maestro-a-monitor.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://blog.vyvojar.cz/bobris/archive/2009/03/02/maestro-a-monitor.aspx&amp;amp;title=Maestro+a+Monitor" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/03/02/maestro-a-monitor.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://blog.vyvojar.cz/bobris/archive/2009/03/02/maestro-a-monitor.aspx&amp;amp;;title=Maestro+a+Monitor" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/03/02/maestro-a-monitor.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://blog.vyvojar.cz/bobris/archive/2009/03/02/maestro-a-monitor.aspx&amp;amp;;title=Maestro+a+Monitor&amp;amp;;top=1" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/03/02/maestro-a-monitor.aspx"&gt;live it!&lt;/a&gt; |  &lt;a href = "mailto:?body=Thought you might like this: http://blog.vyvojar.cz/bobris/archive/2009/03/02/maestro-a-monitor.aspx&amp;amp;;subject=Maestro+a+Monitor" target="_blank" title = "Post http://blog.vyvojar.cz/bobris/archive/2009/03/02/maestro-a-monitor.aspx"&gt;email it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blog.vyvojar.cz/aggbug.aspx?PostID=229077" width="1" height="1"&gt;</description><category domain="http://blog.vyvojar.cz/bobris/archive/tags/C_2300_/default.aspx">C#</category></item></channel></rss>
