copyright (c) 2004 microsoft corporation, all rights reserved dynamic languages and the cli:...

25
Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Upload: aubrey-melton

Post on 25-Dec-2015

219 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Dynamic Languages and the CLI:IronPython

Jim HuguninMicrosoftCLR Team

Page 2: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Common Language Infrastructure (CLI) A virtual machine for multiple languages

Shared bytecode Intermediate Language (IL) Common type system Standard features JIT, AOT, GC, reflection, …

International standard ECMA and ISO Several open-source implementations

6 major languages in production use today C#, VB.Net, Managed C++, J#, Eiffel and

COBOL Notably missing are Python, Perl, Scheme, …

Page 3: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Missing Dynamic Languages“The CLI is, by design, not friendly to dynamic languages.

Prototypes were built, but ran way too slowly.” – InfoWorld, Aug. 2003

"The speed of the current system is so low as to render the current implementation useless for anything beyond demonstration purposes.“ – ActiveState’s report on Python for .NET

How could Microsoft have screwed up so badly that the CLR is far worse than the JVM for dynamic languages?

Jython shows that dynamic languages can run well on the JVM

Page 4: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

IronPython is… A fast Python implementation for the CLI

Compiles Python source to IL (CLI bytecode) Includes supporting libraries (as managed code) 1.8x faster than Python-2.4 on pystone Runs all of parrotbench at roughly the same speed as

CPython Integrated with the other languages of the CLI

C#, VB, J#, JScript, Cobol, Eiffel, C++, …

An early prototype – version 0.6 Runs pystone and Pie-Thon/parrotbench benchmarks All language features implemented but not well tested A lot of library code to be written or ported Still a few open design questions

Page 5: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

pystones/second

26K34K

58K

0

10

20

30

40

50

60

70

Python-2.1 Python-2.3 IronPython.NET-1.1

Venerable benchmark

dhrystone in Python in

Lib/test/pystone.py only benchmark

that ships with Python

Simple but non-trivial

~200 lines of code Most basic Python

ops Very little OO

IronPython is fast 1.7x faster than

CPython-2.3 running on .Net-1.1

Page 6: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

pystones/second Venerable benchmark

dhrystone in Python in Lib/test/pystone.py only benchmark that

ships with Python Simple but non-trivial

~200 lines of code Most basic Python ops Very little OO

IronPython-0.6 is fast 1.7x faster than

CPython-2.3 running on .Net-1.1

1.8x faster than CPython-2.4 running on .Net-2.0beta1

26K34K

58K

38K

67K

0

10

20

30

40

50

60

70

Python-2.1 Python-2.3 IronPython.NET-1.1

Python-2.4 IronPython.NET-2.0b1

Page 7: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Parrotbench Benchmark “The benchmark here is intended to make Dan

Sugalski's life difficult: there are some standard benchmark thingies (simple random algorithms using basic data types) but also a lot of play with odd corners of the language definition, and Python's extremely dynamic object model: funky descriptors, mutable classes, that sort of thing.” – Guido van Rossum

This is a great benchmark for alternative implementations of Python

It only runs correctly if the implementation can handle the range of dynamic features that make Python what it is

Page 8: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

IronPython on parrotbench

4% slower than Python-2.3 (need to update)

0 1 2 3 4 5 6 7 8 9

Python-2.3

IronPython

time (seconds)

b0 b1 b2 b3 b4 b5 b6

Page 9: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Brief parrotbench analysis Half benchmark and half compliance test

Captures the most dynamic extremes This is a great test to have

IronPython is faster on 3 out of 6 tests And tied on 1 of the 6

Performance on both slow tests is dominated by exception handling (but b5 is dominant) throwing and catching an exception is ~3x

slower in IronPython function calls are ~3x faster in IronPython This is the right kind of trade-off

Page 10: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Maybe the CLI can be great for dynamic languages“IronPython: .NET *is* a good platform for dynamic languages” –

GameDev.Net, March 2004

“Before IronPython, the common wisdom was that it was difficult to make dynamic languages perform well on the CLR.” – Edd Dumbill, July 2004

“There was a meme floating around, a few years ago, that the CLR is inherently unfriendly to dynamic languages. As one of the transmitters of that meme, I'm delighted to be proved wrong.” – Jon Udell, InfoWorld, July 2004

And many, many more of these new comments

What makes the difference?

Page 11: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

IronPython Architecture

Same architecture as CPython scanner, parser, bytecode generator, support library

Difference is in bytecode and support library Bytecode is IL for the CLR – will produce native code Support lib is written in C# instead of C

Compilation can be static or dynamic Produces .exe/.dll or dynamically load and run

IronPython is now written completely in C# I built 3 prototypes in Python to throw away After I understood the design I moved to C#

PythonSource File

orCode

Snippet

PythonScanner Tokens

PythonParser AST

ILGenerator IL CLR

IronPython.Objects

refs

Page 12: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Compiling Factorial – to IL

0 LOAD_FAST 0 (n) IL_0000: ldarg.0

3 LOAD_CONST 1 (1) IL_0001: ldsfld object __main__::c$0$PST04000002

6 COMPARE_OP 2 (==) IL_0006: call object IronPython…Ops::Equal(object,object)

9 JUMP_IF_FALSE 8 (to 20) IL_000b: call bool IronPython...Ops::IsTrue(object)IL_0010: brfalse IL_0020

12 POP_TOP

13 LOAD_CONST 1 (1) IL_0015: ldsfld object __main__::c$0$PST04000002

16 RETURN_VALUE IL_001a: ret

def factorial(n):     if n == 1: return 1     return n * factorial(n-1)

Page 13: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Compiling Factorial – to x86

0 LOAD_FAST 0 (n) 0000001b mov edx,dword ptr ds:[01B054E4h] 00000021 mov ecx,esi

3 LOAD_CONST 1 (1)

6 COMPARE_OP 2 (==) 00000023 call dword ptr ds:[036E3184h]

9 JUMP_IF_FALSE 8 (to 20) 00000029 mov edi,eax 0000002b mov ecx,edi 0000002d call dword ptr ds:[036E3084h] 00000033 mov edi,eax 00000035 test edi,edi 00000037 je 00000043

12 POP_TOP

13 LOAD_CONST 1 (1) 00000039 mov eax,dword ptr ds:[01B054E4h]

16 RETURN_VALUE <pop 4 registers and ret>

Page 14: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Compiling Factorial – to C#def factorial(n):    if n == 1: return 1    return n * factorial(n-1)

public static object factorial_f1(object n) { if (Ops.IsTrue(Ops.Equal(n, Main.c_1))) return Main.c_1;   return Ops.Multiply(n, Ops.Call(Main.factorial,                           Ops.Subtract(n, Main.c_1)));}

Page 15: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Compiling Factorial – to C# v2

def factorial(n):    if n == 1: return 1    return n * factorial(n-1)

public static object factorial_f1(object n) { if (Ops.EqualIsTrue(n, 1)) return Main.c_1;   return Ops.Multiply(n, Ops.Call(Main.factorial,                           Ops.Subtract(n, Main.c_1)));}

Page 16: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Ops.EqualIsTrue

This adds a new fastpath “opcode”

public static bool EqualIsTrue(object x, int y) { if (x is int) return ((int)x) == y;

return IsTrue(Equal(x, y));}

Page 17: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Compiling Factorial – x86 v2

0 LOAD_FAST 0 (n) 0000001b mov ecx,esi 0000001d mov edx,1 3 LOAD_CONST 1 (1)

6 COMPARE_OP 2 (==) 00000023 call dword ptr ds:[036E3184h]

9 JUMP_IF_FALSE 8 (to 20) 00000028 mov edi,eax 0000002a test edi,edi 0000002c je 00000038

12 POP_TOP

13 LOAD_CONST 1 (1) 00000039 mov eax,dword ptr ds:[01B054E4h]

16 RETURN_VALUE <pop 4 registers and ret>

Page 18: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Does this affect performance?

Start with a micro-benchmark

def t2(): for i in L: if i == 1000000: break <snip 18 identical lines> if i == 1000000: break

Page 19: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Does this affect performance?

Millio

ns o

f if tests p

er

seco

nd

7 11 16 1521

69

0

10

20

30

40

50

60

70

80

Python-2.1 Python-2.3 Python-2.4 IronPython on1.1

IronPython on2.0

IronPython on2.0 w/opt

Page 20: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Does this affect performance? >3x benefit on microbench But what impact on real code? Need to judge cost-benefit tradeoffs

What is the right general version? Just int or int and long or something else? Need to do all 6 comparison ops Dual benefit that it reduces code size and increases

perf in common case However, this reduces perf if the comparison is not

with an int because a new boxed value will need to be created on the fly

FYI – This particular optimization is not in IronPytho-0.6 because it seemed too special purpose

Page 21: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

How to get good performance Use native CLR constructs whenever possible

Ludicrously optimized machine code But must be used creatively to match Python’s semantics

Create fast-paths for common cases Python scripts to generate C# code at development time Reflection.Emit to generate IL at runtime Some paths might be worth writing by hand Challenge is to figure out what merits a fast-path!

Include fall-backs to fully dynamic implementations General-purpose support for less common cases Handles Python’s fully dynamic semantics

Measure, measure, measure 100’s of small decisions not one large one

Page 22: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Ease of language experimentation C# is a lot more fun to write than C/C++

And Visual Studio 2005 makes this really nice IL is a lot more fun to write than x86/PowerPC/…

And Reflection.Emit library makes this really simple Performance can be extremely competitive

Can leverage huge effort on core CLR Ease of development plays a significant role here

Some very nice tools CLR Debugger – source debugger for any lang + machine

code peverify – checks for safe IL and generates clear easy to

understand errors for buggy compiler generated IL ildasm/ilasm – nice command-line and GUI IL tools Lutz Roeder’s Reflector – a very nice way to inspect

assemblies Visual Studio 2005

Page 23: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Integration is more important than performance

Demo

Page 24: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

A few open design questions How many kinds of strings? i.e. difference

between unicode and ascii? How to handle locals() and

sys._getframe().f_locals? How to interoperate with other dynamic

languages? How to most effectively expose Python code to

other CLR languages

What about unboxed ints like smalltalk and some schemes?

How to support continuations? …

Page 25: Copyright (c) 2004 Microsoft Corporation, All Rights Reserved Dynamic Languages and the CLI: IronPython Jim Hugunin Microsoft CLR Team

Copyright (c) 2004 Microsoft Corporation, All Rights Reserved

Conclusions The CLI is a great platform for language development Ease of development is key

C# is a lot more fun to write than C/C++ And Visual Studio 2005 makes this really nice

IL is a lot more fun to write than x86/PowerPC/… And Reflection.Emit library makes this really simple

Performance can be extremely competitive Ease of development plays a significant role here

Best effort to date for language interoperability 6 major languages in production today Easy interoperability among these

Tools and libraries are powerful and fun

Why not leverage hundreds of man-years of VM development?