- Spolupráce OpenSSL a RSACryptoServiceProvider
-
Pokud bychom chtěli šifrovat RSA mezi OpenSSL (např. v PHP) a .NETovou platformou pomocí třídy RSACryptoServiceProvider-u narazíme na jeden velký problém. OpenSSL a RSACryptoServiceProvider používají jiné formáty klíčů.
Naštěstí existuje řešení:
- Stáhnout OpenSSL - http://www.openssl.org/
- Vygenerovat soukromí klíč (pro demostraci s výchozími parametry):
openssl genrsa -out private.pem - Vygenerovat veřejný klíč:
openssl rsa -pubout -in private.pem -out public.pem - Stáhnout utilitu OpenSSLKey - http://www.jensign.com/opensslkey/, která dokáže převést klíč z formátu generovaného OpenSSL do .NETového.
Bohužel se mi touto utilitou podařilo převést pouze soukromý klíč. Konverze veřejného klíče způsobila chybu v programu. Naštěstí to ale u veřejného klíče nevadí.
- Převedený formát klíče se lze načíst metodou FromXmlString, kterou má RSACryptoServiceProvider
- Pro získání veřejného klíče v XML formátu je nutné zavolat metodu ToXmlString(false)
Tímto postupem jsme získali soukromý a veřejný klíč pro OpenSSL, tak i pro RSACryptoServiceProvider.
Detaily popisuje článek na http://www.jensign.com/opensslkey/, ve kterém lze stáhnout utilitu OpenSSLKey včetně zdrojového kódu v C#.
- Boo syntax highlighting pro Visual Studio 2010
-
V jenom svém projektu používám skriptovací jazyk Boo, o kterém jsem před nedávnem
psal ve svém seriálu o skriptování. A pořád mě trápilo to, že se po otevření ve Visual Studiu otevírá jako obyčejný textový soubor. Trochu jsem zapátral zkusil naprogramovat Classifier (zase nová terminologie označující třídu, která má na svědomí rozebírání textu na barevné kousky).
Mimochodem... nové Visual Studio 2010 má v sobě zabudovanou hezkou podporu pro doplňky VSX a po rychlé prohlídce API se zřejmě můžeme těšit na opravdu velmi velké množství (a doufám kvalitních) doplňků. ... ale zpět.
Velmi hezký článek, který popisuje všechny věci a souvislosti vlastnosti okolo syntax highlightingu je: LearnVSXNow! #38 - VS 2010 Editor - Text Coloring Sample Deep Dive Také je dobré se inspirovat přímo z příkladů blogu o VSX - New Editor Samples for Visual Studio 2010 Beta 1. Pár příkladů nebo řešení už google vrací, takže není problém. :)
A teď k mému projektu. Jak už nadpis říká, jedná se o zvýrazňování syntaxe jazyka Boo. Je to velmi jednoduché zvýrazňování a lexikální analyzátor jazyka jsem přebral z projektu BooLangStudio.
A na závěr samotný projekt:
Boo syntax highlight for Visual Studio 2010 na CodePlexu.
PS: Kdybyste měl někdo nápad, jak nějak pěkně ukázkově vyřešit víceřádkové komentáře budu velmi rád. :)
- WPF: ListBox a vyhledávání pomocí klávesnice
-
Funkce inkrementálního vyhledávání v ListBoxu je velmi užitečná věc. Ani jsem si nevšiml, že ji používám tak často, dokud jsem nezjistil, že ve WPF je tato vlastnost vypnuta (by default). Vyhledávání zapíná vlastnost IsTextSearchEnabled, kterou implementuje ItemsControl (vyhledávání tedy funguje v ListBoxu, ComboBoxu a dalších ovládacích prvcích založených na položkách).
Jak ale docílit toho, abychom mohli vyhledávat v položkách, které jsou např. business třídy – tedy ne ListBoxItem? Návrháři WPF mysleli i na tento problém – stáčí použít TextSearch.TextPath vlastnost, která určí cestu pro inkrementální vyhledávání pomocí klávesnice. Asi nejlepší bude názorný příklad:
Mějme jednoduchou business třídu:
class SimpleClass
{
public Firstname {get;set;}
public Lastname {get;set;}
}
A chtěli bychom inkrementálně vyhledávat podle příjmení:
<ListBox IsTextSearchEnabled="True" TextSearch.TextPath="Lastname">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Firstname}" />
<TextBlock Text="{Binding Lastname}" Margin="10,0,0,0" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Snad tento jednoduchý příklad stačí i jako závěr. :)
- Add-in Regionate - udělejte si pořádek :)
-
Celou dobu si říkám, že by to chtělo nějaký Add-in do Visual Studia, který by dokázal nějakým způsobem uklidit metody, vlastnosti, události... a vůbec všechno tak, aby byla struktura kódu přehlednější. Například rozházet metody a vlastnosti do regionů – to by úplně stačilo. Bohužel jsem si to celou dobu říkal, ale až dnes vygůglil add-in, který mohu doporučit. Jmenuje se Regionate, je zdarma a dokonce open source. Je v něm obsaženo pár základních způsobů formátování a další lze přidat editací XML souboru.
Možná Regionate znáte, nebo používáte jiný způsob úklidu kódu ve třídách. Mně tento nález udělal radost, protože tuto funkci už dlouho postrádám.
- WPF: Ladění data bindingu
-
Pokud binding píšete ručně přímo v XAMLu, určitě mi dáte za pravdu, že se občas překlepnete nebo přehlédnete a binding prostě nefunguje. O tom, jak ladit data binding ve WPF vyšlo už poměrně hodně článků např. How can I debug WPF bindings? od Bea Stollnitze, který popisuje několik technik ladění.
Nejvíce se mi osvědčilo nadění pomocí Converteru. Converter je třída, která je zděděná z IValueConverter a můžeme pomocí něho udělat jakousi transformaci dat na požadované datové typy. Jako jeden z příkladů budiž projekt WPF Converters na CodePlexu, který obsahuje poměrně velké množství v praxi hodně užitečných konvertorů.
Můj Converter pro ladění vypadá takto:
public class DebugConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
System.Diagnostics.Debugger.Break();
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
System.Diagnostics.Debugger.Break();
return value;
}
}
Princip je jednoduše takový, aby při konverzi hodnoty vyskočila výjimka. Potom si můžeme ve Visual Studiu prohlédnout hodnotu, která by se konvertovala v parametru value.
Pokud by k výjimce vůbec nedošlo, znamená to, že se Converter nepoužil a tím pádem se pravděpodobně jedná o překlep v názvu vlastnosti (Property), kterou chceme svázat bindingem.
Použití Converteru je velmi jednoduché, je potřeba ho jenom přidat do Resource, abychom ho mohli použít jako StaticResource:
<Window.Resources>
<DebugConverter x:Key="DebugConv" />
</Window.Resources>
A potom použít v bindingu, který chceme prověřit:
<Label Content="{Binding ElementName=myTextBox, Path=Text, Converter={StaticResource DebugConv}}" />
A motivační poznámka na závěr. Vytvořit tento ladící Converter zabere opravdu mnohem méně času než metodou pokus omyl zjišťovat, kde je chyba. (Vlastní zkušenost) :)
- WPF: Tahák na data binding
-
Dnes zase jen stručně a v podstatě jedním odkazem. Pokud jste (stejně jako já) dost zapomnětlivý nebo se s technologií WPF teprve seznamujete, určitě oceníte WPF XAML Data Binding Cheat Sheet, ve kterém jsou uvedeny všechny základní konstrukce pro tvorbu bindingu ve značkovacím jazyce XAML.
V kombinaci s budoucím Visual Studiem 2010, které už konečné bude podporovat intellisense i pro binding, bude snad psát binding přímo v XAMLu mnohem snazší.
- WPF: Hit testing
-
Hit testing se používá všude tam, kde je potřeba, aby se ověřilo, jestli bod (Point) nebo celá geometrie objektu (Geometry) a vizuální vzhled kontrolního prvku WPF (např. UIElement) spolu kolidují. V praxi se tento test používá asi nejčastěji pro události stisku tlačítek a pohybu myši, kde se na základě hit testu rozhodne, zda vyvolat událost nebo ne.
Pokud bychom chtěli nějaký objekt udělat “průhledný” na vizuální kolize (klikání myší apod.) stačí na něm nastavit IsHitTestVisible = false. Je to užitečné, když potřebujeme události od objektu, který leží pod tímto “průhledným”.
Vlastnost IsHitTestVisible má ale v jednom směru dost nepříjemné chování. Její hodnota se dědí z rodičovského prvku.
Myslím, že nejlepší bude praktická ukázka:
<Canvas x:Name="Klikat" IsHitTestVisible="True">
<Canvas x:Name="Neklikat" IsHitTestVisible="False">
<Ellipse x:Name="Klikat_elipsa" IsHitTestVisible="True" />
</Canvas>
</Canvas>
V tomto případě bychom chtěli docílit toho, aby Canvas s názvem “Klikat” generoval události myši, Canvas “Neklikat” byl průhledný a elipsa “Klikat_elipsa” generovala události. Zde ale narazíme na problém. Vlastnost IsHitTestVisible se totiž dědí z nadřazeného elementu a tím pádem bude mít elipsa vždy IsHitTestVisible = false (ať je v XAMLu nastaveno cokoliv). A události myši bude generovat pouze Canvas “Klikat”.
Jak tedy z toho? Doporučuji přečíst dobrý článek na MSDN o tom, jak funguje Hit testing.
A moje řešení bylo nastavit u všeho IsHitTestVisible = true a “průhlednost” Canvasu “Neklikat” jsem zajistil tak, že jsem vytvořil novou třídu zděděnou z třídy Canvas a v ní jsem přepsal metodu:
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
return null;
}
Tím se zajistila ona “průhlednost” na události myši bez toho, aby byla stejně “průhledná” i elipsa “Klikat_elipsa”.
Na závěr ještě jednou doporučím přečíst článek na MSDN o tom, jak funguje Hit testing, který poskytne návod, jak by se daly řešit mnohem komplikovanější situace.
- WPF: Jak zarovnat prvek vždy na střed v Canvasu?
-
Dnes jenom stručně a v podstatě jedním odkazem, který musím přeposlat dál. :). Jedná se o velmi elegantní řešení, jak zarovnávat prvky v rámci Canvasu - a to jak horizontálně, tak vertikálně. Celé řešení je v chytré implementaci IMultiValueConverter tak, aby centroval. Více ve článku: Centering elements on a canvas in WPF.
- WPF Themes - jednoduše "skinovatelné" aplikace
-
Možná WPF Themes znáte. Jedná se o balík XAML souborů, které jednoduše připojíte k vašemu projektu, přidáte jeden řádek kódu do Application.Resources elementu v souboru App.xaml a hle, váš program vypadá úplně jinak a možná o pár řádů lépe.
Osobně jsem jako programátor trochu ve WPF ztracený. Ne kvůli tomu, že by mi dělalo problémy samotné WPF, ale díky tomu, že umožňuje tolik možností vzhledu a hraní si s grafikou, mi vždycky dojde brzo fantazie a více než polovinu času trávím tím, jak by aplikace mohla vypadat. Určitě by to chtělo nějakého grafika, který by tu představu měl.
Co ale v případě, když grafik jednoduše není? Zkuste napřed WPF Themes, ve kterých lze vybrat nějaký základ. Upravit nějaké detaily už jako programátoři zvládneme. :) Návod a popis lze najít v dokumentaci projektu WPF na Codeplexu.
Důvod, proč jsem se o WPF Themes rozhodl napsat, je jednoduchost celého řešení. Upravit stávající program je opravdu otázkou jednoho řádku v App.xaml a napsat přepínatelný vzhled aplikace není (s inspirací z ukázkového programu) vůbec žádný problém.
Konec šedým okýnkům! :)
- WPF: Syntax Highlight TextBox
-
Založil jsem projekt Simple WPF Syntax Highlight TextBox na CodePlexu. Jak už název napovídá, jedná se o projekt s cílem vytvořit jednoduchý TextBox k editaci zdrojových kódů. Budu se snažit projekt udržovat a rozšiřovat (doufám), protože se zatím jedná o první veřejnou verzi, která má k dokonalosti pořád daleko.
Vlastnosti
Základní vlastnosti jsou v bodech napsány na domácí stránce projektu, ale tady se o nich taky zmíním:
- Jednoduše definovatelná pravidla obarvování pomocí Brush (ne pouze barva)
- Definovatelné pozadí pomocí Brush (ne pouze barva)
- Libovolná barva kurzoru
- Zvýraznění seznamu slov
- Číslování řádků
- Definovatelná velikost odsazení (Tab size) – Taby se převádí na mezery
- Správné odsazování pomocí tab/shift+tab i pro výběr více řádků
- Nový řádek pomocí enteru (jak jinak? :) ) respektuje odsazení, které bylo na aktuálním řádku
V testovacím programu je ukázka zvýrazňování syntaxe pro jazyky IronPython (používá Dynamic Language Runtime, a tak lze jednoduše upravit pro jakýkoliv DLR jazyk) a pro Boo (používá upravený oficiální lexikální analyzátor jazyka Boo).
Vlastní myšlenka, kterou popisují např. články CodeBox2 Project na CodeProject a DevHawk CodeBox, je v tom, že se původnímu TextBoxu nastaví napevno transparentní text a zajistí se vlastní vykreslování v metodě OnRender.
Co dál?
V dalších verzích se můžete těšit na zvýrazňování celých řádků, např. pro breakpointy, chyby, apod. A také na jednoduché doplňování kódu (intellisense), které bude implementováno pro jazyk Boo.
- WPF: Pekelný designer ve VS 2008
-
WPF designer ve Visual Studiu 2008 začínám pomalu vnímat jako určitý druh umělé inteligence. :) Chápu, že v tak rozsáhlém programu jako je VS, může být nějaká chyba, ale tohle mě opravdu dostalo.
Svůj UserControl mám v jiné assembly než vlastní program. Jsem na takové členění zvyklý, a tak to prostě chci. Pokud ale UserControl použiji v programu, správně nadefinuji namespace v XAMLu, tak to bláznivé Visual Studio píše, že nemohlo najít danou assembly
(Assembly 'xyz' was not found. The 'clr-namespace' URI refers to an assembly that is not referenced by the project.)
a Bůh ví, co ještě. Ale ta assembly tam je! Však to po spuštění funguje normálně.
Nebudu vás napínat. Problém byl v tom, že si projekty třídím podle programovacího jazyka, ve kterém jsou napsané a tento byl v adresáři C#. Milý designer totiž nemá rád, když je ‘#’ (mřížka) někde v cestě. Nechápu, ale budiž. Adresář jsem přejmenoval na “CSharp” a všechno funguje jak má.
Pokud se setkáte s touto chybou, doporučuji přečíst jedno delší vlákno na fórech MSDN, které se touto chybou zabývá.
Přeji pevné nervy. :)
- Skriptování v Silverlightu
-
Dnes jenom stručně. :) Někdo se mě v komentářích u seriálu o skriptování ptal, jestli je možné použít některý ze skriptovacích jazyků pro Silverlight. Podařil se mi najít velmi hezký příklad, kde je porovnání mezi použitím DLR (Dynamic Language Runtime) konkrétně IronPython a jazyka Boo.
Protože implementace jazyka IronPython nad DLR musí mít k sobě ještě poměrně velké množství kódu, slouží tento příklad pro porovnání velikostí, které v případě Silverlightu hrají roli:
IronPython zhruba 1,15 MB
Boo zhruba 46 kB
To může být také významný rozhodovací faktor při volbě skriptovacího jazyka.
Detaily včetně zdrojových kódů můžete najít na projektu Tetrisu (lazunin.com).
- WPF: Kontejner pro editaci objektů
-
Předem se omlouvám za nadpis. Nenapadá mě totiž, jak lépe pojmenovat věc, kterou určitě všichni znáte z (převážně vektorových) grafických editorů, a kterou můžete vidět na následujícím obrázku v akci:
Jedná se o kontrolní prvek zděděný z ContentControl (tedy takový, který umožňuje mít do sebe zanořený nějaký obsah) a umožňuje přesuny, změnu velikosti a rotaci jiného prvku, který je uvnitř.
Vycházel jsem z článku WPF Diagram Designer: Part 1, ale chtěl jsem, aby můj kontrolní prvek měl následující vlastnosti:
- Jednoduché použití (příklad v závěru článku)
- Možnosti přesunů, změny velikosti a rotace
- Kurzory nezávisle na nastavení Windows
- Kurzory správně vzhledem k úhlu natočení
- Možnost definovat Brush (barvu) úchopových okrajů
- Možnost dalšího rozšiřování (tedy ne jenom styl ContentControl-u)
Příklad
<Window x:Class="ObjectMoveTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:con="clr-namespace:WPFUtils;assembly=WPFUtils"
Title="Window1" Height="600" Width="800">
<Canvas>
<con:ObjectTransformContainer Width="300" Height="200" SelectionBrush="Red" Canvas.Left="50" Canvas.Top="50">
<MediaElement Stretch="Fill" x:Name="mediaElement" Source="./test/movie.wmv" IsHitTestVisible="False"/>
</con:ObjectTransformContainer>
</Canvas>
</Window>
Závěr
Pro lepší představu a použití ve vlastních projektech nabízím celý projekt ke stažení. Doufám, že se bude někomu hodit. :)
- Skriptování v .NETu 9 (Praktické testy, System.AddIn)
-
Ačkoliv by se předchozí díl mohl zdát (podle názvu) závěrečný, opak je pravdou. :) Kategorie, ve kterých jsem skriptovací jazyky testoval, měly totiž jeden společný parametr – byly závislé na komunikaci mezi skriptem a hlavním programem. Další parametr, který nás zajímá, je rychlost vyhodnocování samotného skriptu.
L-Systém fraktály
Vytvořil jsem jednoduchý testovací program, který vykresluje L-Systém fraktály. K ovládání vykreslovacího kurzoru (želvičky) se nepoužívá gramatika, ale právě různé skriptovací jazyky. Pro více informací o tomto druhu fraktálů doporučuji článek L-Systémy: přírodní objekty i umělé artefakty, který vyšel na serveru Root.cz. Aby měly skriptovací jazyky alespoň nějakou práci, budou vykreslovat kapradinu, kterou můžete vidět na obrázku:
Nemá cenu popisovat jednotlivé metody želvičky. Pro podrobnosti si, prosím, stáhněte celý projekt v závěru článku. Snad jen pro úplnost pseudokód, který vykonávaly všechny testovací skriptovací jazyky:
function Fern(size)
if size <5 then
return
end
turtle.Forward(size / 20)
turtle.Left(80)
Fern(size * 0.3)
turtle.Right(82)
turtle.Forward(size / 20)
turtle.Right(80)
Fern(size * 0.3)
turtle.Left(78)
Fern(size * 0.9)
turtle.Left(2)
turtle.Backward(size / 20)
turtle.Left(2)
turtle.Backward(size / 20)
end
Fern(300)
System.AddIn Framework
Už nadpis sliboval průzkum technologie System.AddIn (.NET 3.5) – jedná se o framework, pomocí kterého můžeme poměrně jednoduše vyvinout aplikaci rozšiřitelnou pomocí zásuvných modulů. Tento framework má výhodu hlavně v tom, že umožňuje řešit zpětnou kompatibilitu jednotlivých zásuvných addinů, možnost jejich uvolnění z paměti a ochranu hlavního programu proti chybě v addinu (addiny běží v oddělené AppDomain).
O System.AddIn Frameworku toho bylo napsáno poměrně hodně a určitě stojí za prozkoumání. Mohu doporučit:
Co je důležité pro naše testovaní je fakt, že práce s Addinem (pluginem, zásuvným modulem, jak chcete...) určitě bude trvat nějaký čas navíc, protože hlavní program musí komunikovat s jinou AppDomain. O rychlosti komunikace rozhoduje, jestli se předávaný objekt mezi addinem a hlavním programem předává hodnotou serializovaný (atributem [Serializable]) nebo odkazem (zděděný ze třídy MarshalByRefObject).
Testování
Test ukazuje, jak rychle lze volat metody proměnné (instance určité třídy, která byla vytvořená v hlavním programu) ze skriptu. Testování nezahrnuje režii, která je potřeba k vytvoření testovacího engine. Proto testujeme pouze následující kroky:
- Parsování a kompilace (vyhodnocení) skriptu.
- Předání vytvořené instance želvičky.
- Rekurzivní vykreslení kapradiny ve skriptovacím jazyku.
V testování System.AddIn frameworku se testuje pouze to, jestli je objekt želvičky předáván mezi AppDomain:
Dobu potřebnou ke komunikaci mezi AppDomain jsem měřil tak, že jsem vypočítal rozdíl mezi dobou výpočtu v hlavním programu a napevno naprogramovaným kódem v addinu (bez použití skriptovacího jazyka).
Pár poznámek: Skriptovací knihovna DotScript, kterou jsem popisoval v prvním dílu seriálu, se neosvědčila – metoda, která měla přidat referenci na assembly s želvičkou, nefungovala. Omluvou budiž to, že je knihovna DotScript v beta verzi (bohužel jsem neměl čas problém blíže zkoumat). DotScript jsem proto nahradil parsováním C# pomocí CodeDomProvideru.
Také je třeba poznamenat, že v PowerShellu se mi nepodařilo (ačkoliv jsem zkoušel na hodně místech použít přetypování na celá čísla) docílit vykreslení kapradiny stejně. Kapradina se vykreslí bohatší, což PowerShell trochu znevýhodňuje – ale nemělo by moc zásadně.
Testování probíhalo na počítači s procesorem Intel Core Duo 2 (P8400) @ 2.26 GHz, 4 GB RAM, operační systém Windows Vista Ultimate.
Výsledky
| Jazyk | MarshalByRefObject | [Serializable] |
| Lokální výpočet | 70 ms | 71 ms |
| Výpočet v addinu | 937 ms | 3090 ms |
| Boo | 1026 ms | 3258 ms |
| C# | 970 ms | 3125 ms |
| IronPython | 3590 ms | 5173 ms |
| IronRuby | 2856 ms | 5155 ms |
| JScript .NET | 1475 ms | 5097 ms |
| Lua | 2506 ms | 5979 ms |
| PowerShell | 408669 ms | 411687 ms |
| |
| Komunikace | 866 ms | 3018 ms |
A nyní trochu grafů... :)
Protože se z grafů s logaritmickým měřítkem těžko odhadují poměry komunikací mezi AppDomain a vlastním prováděním skriptů, udělal jsem ještě 2 grafy, kde je poměr hezky vidět. Na těch už není PowerShell, který by je svým dlouhým časem zkresloval.
Závěr
V tomto praktickém testu se opět ukázalo, že skriptovací jazyky můžeme rozdělit do 3 skupin, které jsou zhruba stejně rychlé:
- Ty, které se překládají do CIL (C#,Boo,JScript).
- Ty, které používají Dynamic Languga Runtime (IronPython, IronRuby).
- Ostatní – poměrně rychlá Lua, a velmi pomalý PowerShell.
Také jsem chtěl ukázat, jaký vliv může mít opakované používaní objektu z jiné AppDomain a jaký vliv na to má předávaní odkazem (MarshalByRefObject) a hodnotou ([Serializable]).
Pro vytvoření tohoto ukázkového programu bylo použití jiných AppDomain nezbytné, protože současná verze IronRuby a IronPython používá sice stejné assembly Dynamic Language Runtime, ale jiné verze. Jindy je třeba toto řešení zvážit z důvodu režie, kterou má komunikace mezi AppDomian.
Pro detaily k jednotlivým skriptovacím jazykům, prosím, zavítejte do předcházejících dílů seriálu.
Ke stažení
Myslím, že na závěr by se slušelo dát ke stažení celý projekt pro vykreslování L-Systém kapradiny pomocí skriptů.
Testovací program byl vytvořen narychlo a pouze pro účely testování, tak prosím o kolegiální toleranci. :)
- Skriptování v .NETu 8 (Závěrečné porovnání)
-
Dost bylo jednotlivých skriptovacích jazyků. Myslím, že jsem vybral zástupce nejčastějších a nejzajímavějších jazyků, které by se pro .NETové prostředí daly použít. Pojďme je nyní porovnat a shrnout jejich klady a zápory.
Pro úplnost uvádím seznam skriptovacích jazyků s odkazy na jednotlivé díly seriálu, které jsme zatím prozkoumali:
- DotScript (jazyky C# a VB)
- IronPython
- IronRuby
- Lua
- Boo
- JScript .NET
- PowerShell
Tyto jazyky by se daly rozdělit do třech skupin. Skupina jazyků, které jsou implementovány nad Dynamic Language Runtime – IronPython, IronRuby.
Skupina jazyků, které jsou pomocí CodeDomProvideru nebo jinak překládány přímo do CLI, a dále se reflexí pracuje s vytvořenými třídami a voláním funkcí nebo metod. – DotScript, Boo, JScript .NET.
Poslední zbývající jazyky jsou: Lua (používá plně managed knihovnu LuaInterface) a PowerShell, který není třeba představovat.
Vyhodnocení
Skriptovací jazyky jsem porovnával v sedmi kategoriích, které si popíšeme. Základem vyhodnocení je následující tabulka, ve které jsou zaznamenané časy jednotlivých měření (v milisekundách). Každý test se opakoval milionkrát. U některých měření jsem musel změnšít počet opakování z důvodu velké časové náročnosti (výsledný čas jsem samozřejmě vynásobil, aby bylo měření poměrově v pořádku).
| | DotScript | IronPython | IronRuby | Lua | Boo | JScript .NET | PowerShell |
| Parsování / kompilace (první) | 160 | 1600 | 1450 | 300 | 750 | 125 | 1300 |
| Parsování / kompilace (opakovaná) | 160 | 50 | 50 | 20 | 100 | 80 | 130 |
| Float test | 1753 | 18451 | 2045800 | 60884 | 2070 | 2310 | 3714700 |
| Faktoriál test | 2260 | 21981 | 2096220 | 18815 | 2534 | 4669 | 19126400 |
| Zápis do skriptu | 1860 | 4086 | 502 | 2059 | 598 | 641 | 1200 |
| Čtení ze skriptu | 1835 | 4092 | 443 | 1767 | 524 | 554 | 1100 |
| Vytvoření instance | 7644 | 14353 | 2928030 | 5267 | 3448 | 3075 | 4626000 |
Nyní si rozeberme jednotlivé kategorie a ke slovu přijdou slibované grafy. :)
Parsování / kompilace (první)
V tomto čase se hodně projevuje režie, která je z větší části dána načítáním potřebných assembly.
Zde trvá nejdéle inicializace skriptovacích jazyků založených na Dynamic Language Runtime.
Parsování / kompilace (opakovaná)
Při opakované inicializaci skriptovacího engine jsou už všechny assembly nahrané, a tak čas vypovídá o zpracování zdrojových kódů.
V tomto testu zvítězil jazyk Lua, který je v tomto směru rychle zpracovatelný.
Float test
Tento test měl změřit, jak rychle si skript dokáže poradit s výpočtem rovnice
sin2(30)+cos2(30), a výsledek (metody/funkce) vrátit hlavnímu programu. Čas udává milion opakování testu.
V tomto testu jsou nejlepší jazyky, které jsou přímo překládány do CIL.
Osa Y je v logaritmickém měřítku.
Faktoriál test
Test spočíval ve výpočtu faktoriálu čísla 12 (tedy 12!) rekurzivním voláním funkce a vrácení výsledku (z metody/funkce) hlavnímu programu. Čas udává milion opakování testu.
V tomto testu byl o hodně horší PowerShell, ve kterém bylo opakované rekurzivní volání velmi pomalé.
Osa Y je v logaritmickém měřítku.
Čtení hodnoty proměnné ze skriptu
Čtení hodnoty ze skriptu se používá tam, kde je třeba přečíst výsledek, který skript počítal. Jedná se o volání metody, která proměnnou z kontextu skriptovacího jazyka přečte a hodnotu vrátí do hlavního programu. Čas udává milion opakování testu.
Větší čas u jazyka IronPython je dán tím, že se četla členská proměnná testovací třídy namísto globální proměnné u jazyka IronPython.
Zápis hodnoty proměnné do skriptu
Zápis proměnné z hlavního programu se používá zpravidla na začátku před samotným výpočtem. Většinou se jedná pouze o volání metody, která proměnnou v kontextu skriptovacího jazyka nastaví. Čas udává milion opakování testu.
Větší čas u jazyka IronPython je dán tím, že se zapisovala členská proměnná testovací třídy namísto globální proměnné u jazyka IronPython.
Vytvoření instance třídy ve skriptu
Úkolem tohoto testu bylo vrátit instanci třídy ze skriptu tak, aby se mohla v hlavním programu použít. Malou výjimkou zde byl jazyk Lua, který místo objektů používá systém tabulek, ve kterých jsou jak záznamy pro data (členské proměnné), tak pro funkce.
Závěrečné hodnocení
Nyní si u jednotlivých jazyků shrneme klady a zápory podle výsledků a subjektivního názoru na syntaxi. Podrobnější informace k jednotlivým jazykům se můžete dočíst v předcházejících dílech seriálu.
Pokud bychom výpočty ze skriptovacího jazyka potřebovali volat opakovaně (např. při výpočtu animace, apod.), a hodně záleželo na rychlosti, doporučuji využít skriptovací jazyky, které svůj kód před použitím zkompilují do CLI tedy: DotScript, Boo nebo JScript.NET.
DotScript (C# a VB)
Knihovna DotScript je zaobalení CodeDomProvideru a umožňuje zpracovat jazyky C# a VB. Pokud skriptuje programátor, je velká výhoda právě použití těchto jazyků – programátor se nemusí učit nic nového. Z vyhodnocení testů vyplývá, že toto řešení je velmi rychlé. Avšak z testu čtení a zápisu proměnných vyplívá, že DotScript má okolo těchto operací větší režii.
IronPython, IronRuby
IronPython je jazyk, který vyniká svou přehledností i u velkých projektů. IronRuby je zase snadno naučitelný. Oba tyto jazyky jsou implementovány nad Dynamic Language Runtime, což je “podhoubí” pro libovolné skriptovací jazyky. V testech dopadl poměrně dobře IronPython – jeho rychlost by ve většině případů neměla ovlivnit aplikaci. U IronRuby se to říci nedá. Bohužel testy ukázaly pomalost např. při výpočtu faktoriálu.
Lua
Tento jednoduchý jazyk byl nejrychlejší ve zpracování zdrojového kódu skriptu. Ve vyhodnocování byl průměrný. Ovšem ve výsledku se jedná o velmi dobré řešení, které v mnoha úlohách splní svůj účel.
Boo
Tento jazyk byl pro mne milým překvapením, protože jsem ho do té doby neznal. Je stejně přehledný jako Python (byl jím inspirován) a má velkou rychlost z důvodu kompilace do CLI před použitím. Ze subjektivního poměru rychlost/syntaxe ho považuji za vítěze testů.
JScript .NET
Tento jazyk představuje etalon v rychlosti skriptování. V článku o JScript .NET jsem ukázal použití CodeDomProvideru, což je asi nejoptimálnější způsob, jak v .NETu skriptovat, pokud můžeme použít reflexi k operacím mezi skriptem a hlavním programem. Syntaxe JScript .NET je také výhodná, pokud by měl psát skripty někdo se znalostmi JavaScriptu – např. webový vývojář.
PowerShell
Tento jazyk jsem zařadil z čisté zvědavosti, protože mě zajímala jeho integrace do .NETových programů. Bohužel mě trochu zklamala pomalost, ale ta může být za určitých podmínek vykoupena známostí PowerShellu a dostupnou dokumentací.
Závěr
Doufám, že vám tato moje malá exkurze do světa skriptovacích jazyků trochu pomohla s určením toho, který z nich je pro vás v daném případě nejvhodnější.
Pro úplný závěr seriálu chybí ještě jeden test – nějaký z praxe, na kterém by se ukázaly naplno klady a zápory daného jazyka. Proto poslední článek tohoto seriálu bude o praktickém použití. Přiložím také zdrojové kódy, ve kterých bude vidět integrace jednotlivých skriptovacích jazyků.
PS: Můžete se těšit na želvičku! (Vykreslování L-System fraktálů) :)