Anpassbare Software mit dem .NET Framework: Compilieren statt interpretieren Ralf Westphal Freier Fachautor & Berater Microsoft Regional Director [email protected].

Download Report

Transcript Anpassbare Software mit dem .NET Framework: Compilieren statt interpretieren Ralf Westphal Freier Fachautor & Berater Microsoft Regional Director [email protected].

Anpassbare Software mit dem
.NET Framework:
Compilieren statt interpretieren
Ralf Westphal
Freier Fachautor & Berater
Microsoft Regional Director
[email protected]
Anwendungen anpassen

Aussehen/Funktionalität ohne
Neuübersetzung ändern
•
•
•

Möglicherweise beim Anwender
Parametrisierung
•
Beliebige Anzahl Werte
Scripting
•
Funktionalität mit Algorithmen beschreiben
Anpassbarkeit gewinnt an Bedeutung
•
Anpassen einer Standardapplikation ist
meist billiger als Spezialentwicklung
Scripte


Beschreibung davon „was zu tun ist“
Kein spezifisches Format
•
•

Textuelle Formate
•
•
•
Imperative Programmiersprachen (z.B. VBScript)
Deklarative Programmiersprachen (z.B. reguläre Ausdrücke,
XSLT)
Eigene Formate (z.B. XML-basiert)
Strukturierte Formate
•
Relationale Datenbanken (z.B. industrieelle Stücklisten)
Beispiele
•
Reguläre Ausdrücke, ad hoc Ausdrucksberechnung,
Validation, Administration, mobile Agenten,
Ereignisbehandlung
Interpretation



Per definitionem werden Scripte interpretiert
•
•
Scriptformat nicht direkt ausführbar
Applikation bestimmt „Bedeutung“ von Script/Parametern
• Script wird geparst (Erkennung von Anweisungen)
• Applikation führt Anweisungen aus, die den
Applikationszustand beeinfluss
Vorteile
•
•
•
Flexibilität
Meist einfach zu implementieren
Meist einfach zu installieren
Nachteile
•
•
Schlechte Performance
Scripte sind leicht einzusehen
Demo

Ausdrucksberechnung
Performance Killers

Wiederholtes Parsen
•
•
•


Textuelle Repräsentation aufbrechen
•
•
Lexikale Analyse (Symbole erkennen)
Syntaktische Analyse (Anweisungen erkennen)
Typumwandlung
•
Text in angemessenen Datentyp wandeln
Alternative: Spezielle Datenstrukturen traversieren (z.B.
Datenbank, XML)
Wiederholte Interpretation
•
Immer wieder bestimmen, was zu tun ist – statt es einfach zu
tun
Mögliche Verbesserung:
•
Script einmalig in eine internet Zwischendarstellung wandeln
(Abstrakter Syntaxbaum (AST))
Demo

Ausdrucksberechnung mit AST
Performance Boost



Übersetzung in ausführbaren Code
•
•
Einmaliges Parsen
Einmalige Interpretation
•
Resultat: Ausführbarer Code, der einfach das
tut, was mit einem Script beabsichtigt war
Vorteil
•
Rohe Geschwindigkeit
Nachteil
•
Schwer zu implementieren
Es wie .NET tun...


Compilation statt Interpretation
Scripte sind überall
•
•
•
•
Reguläre Ausdrücke
XML-Serialisierung
ASP.NET Seite
XML Web Service Proxy
•
•
XPath Queries
XSLT Transformationen
Demo





RegEx
XML-Serialisierung
XPath
ASP.NET Seite
XML Web Service Proxy
Es ist einfach!

Neue Technologien machen
Codegenerierung sehr einfach
•
•
•
IL als Fundament
CodeDOM
•
•
Sourcecode on-the-fly compilieren
AST zur Laufzeit zusammenbauen und
compilieren
Reflection.Emit
•
Direkt IL erzeugen
Demo




Ausdrucksberechnung durch
Compilation von Sourcecode mit
CodeDOM
... Compilation eines AST
... Ausgabe von IL mit Reflection.Emit
(Assertions und Context Attributes)
CodeDOM I
Sourcecode
on-the-fly compilieren
Dim vbcp As New VBCodeProvider()
Dim vbc As Compiler.ICodeCompiler = vbcp.CreateCompiler
Dim cps As New Compiler.CompilerParameters()
cps.CompilerOptions = String.Format("/libpath:""{0}"" /rootnamespace:{1}", _
Environment.CurrentDirectory, Me.GetType.Namespace)
cps.OutputAssembly = DateTime.Now.Ticks & ".dll"
cps.ReferencedAssemblies.Add("System.dll")
cps.ReferencedAssemblies.Add("ExpressionEvaluator.dll")
Dim cr As Compiler.CompilerResults
cr = vbc.CompileAssemblyFromSource(cps, source)
CodeDOM II
 Aufbau
eines AST
_codeRoot = New CodeNamespace("ralfw.ExpressionEvaluation")
_codeRoot.Imports.Add(New CodeNamespaceImport("System"))
Dim classCe As New CodeTypeDeclaration("CompiledExpression")
classCe.IsClass = True
classCe.Attributes = MemberAttributes.Public
classCe.BaseTypes.Add("CompiledExpressionBase")
_codeRoot.Types.Add(classCe)
Dim funcEval As New CodeMemberMethod()
funcEval.Name = "Eval"
funcEval.Attributes = MemberAttributes.Public Or MemberAttributes.Override
funcEval.Parameters.Add(New CodeParameterDeclarationExpression("Double", "x"))
funcEval.ReturnType.BaseType = "Double"
classCe.Members.Add(funcEval)
_stmReturn = New CodeMethodReturnStatement()
funcEval.Statements.Add(_stmReturn)
Reflection.Emit I
 IL
direkt erzeugen
Dim an As New Reflection.AssemblyName()
an.Name = "re" & DateTime.Now.Ticks.ToString
_asmCompiledExpression = AppDomain.CurrentDomain.DefineDynamicAssembly(an, _
AssemblyBuilderAccess.RunAndSave)
_asmFilename = an.Name & ".dll"
Dim mb As ModuleBuilder = _asmCompiledExpression.DefineDynamicModule(_asmFilename)
_tbCompiledExpression = mb.DefineType("ralfw.ExpressionEvaluation.CompiledExpression", _
TypeAttributes.Public Or TypeAttributes.Class, _
GetType(CompiledExpressionBase))
Dim fb As MethodBuilder = _tbCompiledExpression.DefineMethod("Eval", _
MethodAttributes.Virtual Or MethodAttributes.Public, _
GetType(System.Double), _
New Type() {GetType(System.Double)})
_ilCompiledExpression = fb.GetILGenerator()
Bedenkenswertes




Lexikalische/syntaktische Analyse immer noch nötig
•
XML-Formate können hier helfen
Am einfachsten geht es mit CodeDOM
•
•
Kann Sourcecode erzeugen/übersetzen
Hochsprachenkonstrukte (C# angelehnt)
Reflection.Emit bringt Geschwindigkeit
•
•
•
Codegenerierung
Übersetzung
Flexibilität (geht über C#-Konstrukte hinaus)
Achtung: Dynamisch erzeugte Assemblies können
nicht entladen werden
•
Abhilfe: Hosting in separater AppDomain
Zusammenfassung




Compilation ist heute sehr einfach
•
Compilierte Scripte sind immer schneller als
interpretierte
Compilierte Scripte sind in 99% der Fälle genauso
flexibel
Compilation benutzen, wenn Summe aus
Übersetzungszeit und Laufzeit < Interpretationszeit
•

Wenn Sie einen Parser/Interpreter haben, haben Sie es schon
fast geschafft
Wiederholte Ausführung eines Scripts rechtfertigt
allermeistens eine Compilation
Oder: Compilieren Sie einfach, weil es cool ist 
Fragen!?
Uff...
Ressourcen







Saurabh Nandu, Emitting Dynamic Assemblies on the fly using Reflection.Emit,
Wrox Press, www.csharptoday.com
Peter Huene, Exploring the System.Reflection.Emit Namespace,
http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=238
Brian J. Korzeniowski, Microsoft .NET CodeDom Technology - Part 1-3,
http://www.15seconds.com/issue/020917.htm
Paul Nichols, CodeDOM: How to achieve code generation in .NET,
http://www.devcity.net/net/article.aspx?alias=codedom_1
Nick Harrison, Using the CodeDOM, http://www.ondotnet.com/lpt/a/3155
Tom Archer, Andrew Whitechapel, String Handling and Regular Expressions, in:
Inside C#, MSPress, http://www.microsoft.com/mspress/books/sampchap/5861b.asp
Beispiele:
Über den Referenten
Ralf Westphal ist freier Softwaretechnologievermittler. Er arbeitet als Fachautor,
Coach/Berater, Softwareentwickler und Sprecher auf Konferenzen im In- und Ausland
wie Microsoft Technical Summit, XML-in-Action, BASTA!, COMDEX, Software
Development oder XML One.
Der Schwerpunkt seiner Arbeit liegt bei der Vermittlung und Anwendung moderner
Softwaretechnologien und -konzepte auf der Microsoft Plattform mit Fokus in den
Bereichen OOP/komponentenorientierte Entwicklung, Softwarearchitektur und .NET
Framework.
Darüber hinaus ist Ralf Westphal einer der deutschen Microsoft MSDN Regional
Directors, Mitglied verschiedener Fachbeiräte und war von 1998 bis 2001
Chefredakteur der Visual Basic Fachzeitschrift BasicPro.
Bücher des Referenten
.NET kompakt
140 Seiten, Spektrum Akademischer Verlag, 2002, ISBN 3827411858
ADO.NET Datenbankprogrammierung
130 Seiten , Addison-Wesley , 2002 , ISBN 3827319978
Jetzt lerne ich ADO.NET
Einfache Datenbankprogrammierung im .NETFramework
400 Seiten, Markt+Technik, 2003, ISBN 3827262291 (erscheint im
September)
Empower people
through great software
any time, any place,
and on any device