SlideShare a Scribd company logo
{
"talk": {
"title": "Python on the edge of a razor",
"event_id": "PyConRu_2017",
},
"speaker": {
"__qname__" : "Aleksandr Koshkin",
"linkedin" : "lnkfy.com/7Do",
"github" : "/magniff",
}
}
Rather weird talk on performance
def interprete():
while True:
age = int(input('age: >> ')) # opcode, kind of
# handlers
if age < 6:
print("Ahh %s, Who is a little cutie?" % age)
elif age < 23:
print(
"So, %s ha? How is your school today?" % age
)
else:
print("Go find a job, you hippie!1")
Is it just me, or...
- Frame represents running code
- Code represents instructions and interface for context
PyObject *
PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
{
co = f->f_code;
for (;;) {
switch (opcode) {
TARGET(LOAD_FAST) {* implementation of LOAD_FAST *}
TARGET(LOAD_CONST) {* implementation of LOAD_CONST *}
TARGET(STORE_FAST) {* implementation of STORE_FAST *}
...
}
}
Frame evaluator
TARGET(BINARY_ADD) {
PyObject *right = POP();
PyObject *left = TOP();
PyObject *sum;
...
sum = PyNumber_Add(left, right);
...
DISPATCH();
}
C API
Years of awkward optimisations
>>> def fib(a, b):
while True:
a, b = b, a+b
yield b
>>> f = fib(1, 1)
>>> next(f)
2
>>> next(f)
3
>>> next(f)
5
>>> next(f)
8
Fibonacci generator
>>> dis.dis(fib)
2 0 SETUP_LOOP 26 (to 29)
--------------------------------------------------------------
3 >> 3 LOAD_FAST 1 (b)
6 LOAD_FAST 0 (a)
9 LOAD_FAST 1 (b)
12 BINARY_ADD
13 ROT_TWO
14 STORE_FAST 0 (a)
17 STORE_FAST 1 (b)
4 20 LOAD_FAST 1 (b)
23 YIELD_VALUE
24 POP_TOP
25 JUMP_ABSOLUTE 3
What CPython generates
from cocode import CodeObjectProxy, Constant, Return, Add
code_proxy = CodeObjectProxy(
Constant("Hello "),
Constant("world!"),
Add(),
Return()
)
code = code_proxy.assemble()
assert eval(code) == "Hello world!"
CoCode(https://github.com/magniff/cocode)
def fibonacci(a, b):
pass
fib_asm_code = CodeObjectProxy(
VariableFast('a'),
VariableFast('b'),
# --------------------------------------
Label(Dup(), "loop"),
Rot3(),
Add(),
Dup(),
Yield(),
Pop(),
Jump("loop"),
interface=fibonacci,
)
Fibonacci generator, cocode version
>>> dis.dis(fibonacci)
0 0 LOAD_FAST 0 (a)
3 LOAD_FAST 1 (b)
--------------------------------------------------------------
>> 6 DUP_TOP
7 ROT_THREE
8 BINARY_ADD
9 DUP_TOP
10 YIELD_VALUE
11 POP_TOP
12 JUMP_ABSOLUTE 6
# so, the algorithm is
# a,b -> a,b,b -> b,a,b -> b,a+b -> b,a+b,a+b -> yield a+b and loop back
Using stack machine like a pro
Dit it help?
$ time python fib.py
real 0m0.449s
$ time python fib_asm.py
real 0m0.462s
Dit it help?
PyPy is fast because it is jitted, ok?
This answer does not satisfy me
late binding
boxing
vm overhead
Deadly sins of dynamic programming languages
some_method = some_object.method
for value in huge_list:
some_method(value)
Late binding:
00100000000100101000111100000000
00000000000000000000000000000000
10000000000100101000111100000000
00000000000000000000000000000000
00001111000000000000000000000000
00000000000000000000000000000000
11100000111001001000100100000000
00000000000000000000000000000000
00000001000000000000000000000000
00000000000000000000000000000000
01100100000000000000000000000000
Boxing:
We dont really see it, yet it is there
VM overhead
- negative
Is this the end, mommy?
Example: Say you are asked to sort one
billion numbers, what you gonna do?
The key to performance is specialization
● PyPy: yet another python implementation (fastest on market, though)
● PyPy is written in RPython - turbo ugly subset of python language
● You might think: hmmm, Python, even restricted one - that sounds fun
● It is not, trust me
Before we start: RPython, PyPy etc.
● PyPy: yet another python implementation (fastest on market, though)
● PyPy is written in RPython - turbo ugly subset of python language
● You might think: hmmm, Python, even restricted one - that sounds fun
● It is not, trust me
$ cat demo.py
import os
def main(argv):
os.write(1, 'Is that even legal?n')
return 0
def target(*args):
return main, None
Before we start: RPython, PyPy etc.
$ python2 rpython/bin/rpython -O2 demo.py
Before we start: RPython, PyPy etc.
$ ./demo-c
Is that even legal?
Before we start: RPython, PyPy etc.
[Timer] Timings:
[Timer] annotate --- 3.6 s
[Timer] rtype_lltype --- 0.1 s
[Timer] backendopt_lltype --- 0.1 s
[Timer] stackcheckinsertion_lltype --- 0.0 s
[Timer] database_c --- 8.5 s
[Timer] source_c --- 0.9 s
[Timer] compile_c --- 1.8 s
[Timer] =========================================
[Timer] Total: --- 15.0 s
Before we start: RPython, PyPy etc.
By Davide Ancona, Carl Friedrich Bolz, Antonio Cuni, and Armin Rigo
Automatic generation of JIT compilers for
dynamic languages in .NET
Я испытал мощный эмоциональный подъем
By Yoshihiko Futamura
Having program P, taking inputs s1
...sn
and d1
...dm
S(P, (s1
,..., sm
)) = P’
Produce program P’ such as
P(s1
...sn
, d1
,..., dm
) = P’(d1
,..., dm
)
Partial Evaluation of Computation Process, Revisited
S(P, (s1
, ..., sm
)) = P’
Similar to rendering equation
Similar to rendering equation
Specialization level.
(since it is too static)
Classical partial evaluation has a disadvantage
So, we better obtain
more info at runtime.
(Tempo, DyC)
Classical partial evaluation has a disadvantage
Yes!
Can we go fully dynamic?
TLC
Study case
– Stack manipulation: POP, PUSHARG, SWAP, etc.
– Flow control: BR_COND, BR jumps.
– Arithmetic: ADD, SUB, etc.
– Comparisons: EQ, LT, GT, etc.
– Object-oriented operations: NEW, GETATTR, SETATTR.
– List operations: CONS, CAR, CDR.
TLC language (rpython/jit/tl/tlc.py)
def interp_eval(code, pc, args, pool):
code_len = len(code)
stack = []
while pc < code_len:
opcode = ord(code[pc])
pc += 1
if opcode == PUSH:
stack.append(IntObj(char2int(code[pc])))
pc += 1
elif opcode == PUSHARG:
stack.append (args[0])
elif opcode == SUB:
a, b = stack.pop(), stack.pop()
stack.append(b.sub(a))
elif opcode == LT:
a, b = stack.pop(), stack.pop()
stack.append(IntObj(b.lt(a)))
elif opcode == BR_COND:
cond = stack.pop()
if cond.istrue():
pc += char2int(code[pc])
pc += 1
elif opcode == RETURN:
break
...
return stack[-1]
class IntObj(Obj):
def __init__(self, value):
self.value = value
def lt(self, other):
return self.value < other.int_o()
def sub(self, other):
return IntObj(self.value - other.int_o())
def int_o(self):
return self.value
main:
PUSHARG
PUSH 0
LT
BR_COND neg
pos:
PUSHARG
RETURN
neg:
PUSH 0
PUSHARG
SUB
RETURN
Say we are provided with the following code
Not much.
What static partial evaluator can do?
def interp_eval(code, pc, args, pool):
code_len = len(code)
stack = []
while pc < code_len:
opcode = ord(code[pc])
pc += 1
if opcode == PUSH:
stack.append(IntObj(char2int(code[pc])))
pc += 1
elif opcode == PUSHARG:
stack.append (args[0])
elif opcode == SUB:
a, b = stack.pop(), stack.pop()
stack.append(b.sub(a))
elif opcode == LT:
a, b = stack.pop(), stack.pop()
stack.append(IntObj(b.lt(a)))
elif opcode == BR_COND:
cond = stack.pop()
if cond.istrue():
pc += char2int(code[pc])
pc += 1
elif opcode == RETURN:
break
...
return stack[-1]
def interp_eval_abs(args):
stack = []
stack.append(args[0])
stack.append(IntObj(0))
a, b = stack.pop(), stack.pop()
stack.append(IntObj(b.lt(a)))
cond = stack.pop()
if cond.istrue():
stack.append(args[0])
return stack[-1]
else:
stack.append(IntObj(0))
stack.append(args[0])
a, b = stack.pop(), stack.pop()
stack.append(b.sub(a))
return stack[-1]
Escape analysis
def interp_eval_abs(args):
stack = []
stack.append(args[0])
stack.append(IntObj(0))
a, b = stack.pop(), stack.pop()
stack.append(IntObj(b.lt(a)))
cond = stack.pop()
if cond.istrue():
stack.append(args[0])
return stack[-1] # 0_o
else:
stack.append(IntObj(0))
stack.append(args[0])
a, b = stack.pop(), stack.pop()
stack.append(b.sub(a))
return stack[-1] # 0_o
def interp_eval_abs(args):
v0 = args[0]
v1 = IntObj(0)
a, b = v0, v1
v0 = IntObj(b.lt(a))
cond = v0
if cond.istrue():
v0 = args[0]
return v0
else:
v0 = IntObj(0)
v1 = args[0]
a, b = v0, v1
v0 = b.sub(a)
return v0
def interp_eval_abs(args):
a = args[0]
cls_a = a.__class__
switch cls_a :
IntObj :
if 0 < a.value:
return a
else:
return IntObj(0 - a.value )
default:
try_something_else()
But does this make any
sense?
It depends.
● Apply S function only to hot loops
● Lots of consequent iterations of the loop
take the same path in the CFG
Oook, but the hottest loop in the interpreter is a opcode
dispatch loop.
Assumptions:
Metatracer
Approach (a approach, not the approach):
Automatic handling of such a problems is
extremely difficult task. How about providing
a set of hints?
But still:
myjitdriver = JitDriver(greens = ['pc', 'code'], reds = ['frame', 'pool'])
def interp_eval(code, pc, args, pool):
code_len = len(code)
stack = []
frame = Frame(args, pc)
while pc < code_len:
myjitdriver.jit_merge_point(
frame=frame, code=code, pc=pc, pool=pool
)
opcode = ord(code[pc])
pc += 1
if opcode == some_opcode:
...
elif opcode == BR:
old_pc = pc
pc += char2int(code[pc]) + 1
if old_pc > pc:
myjitdriver.can_enter_jit(
code=code, pc=pc, frame=frame, pool=pool
)
return stack[-1]
def lookup(cls, methname):
...
def call_method(obj, method_name, arguments):
cls = obj.getclass()
...
method = lookup(cls, method_name)
return method.call(obj, arguments)
@elidable
def lookup(cls, methname):
...
def call_method(obj, method_name, arguments):
cls = obj.getclass()
promote(cls)
method = lookup(cls, method_name)
return method.call(obj, arguments)
Somewhat similar to PIC
No, thanks
Any details to metajit in this talk?
:3

More Related Content

What's hot

GoLightly: Building VM-Based Language Runtimes with Google Go
GoLightly: Building VM-Based Language Runtimes with Google GoGoLightly: Building VM-Based Language Runtimes with Google Go
GoLightly: Building VM-Based Language Runtimes with Google Go
Eleanor McHugh
 
EuroPython 2017 - Bonono - Simple ETL in python 3.5+
EuroPython 2017 - Bonono - Simple ETL in python 3.5+EuroPython 2017 - Bonono - Simple ETL in python 3.5+
EuroPython 2017 - Bonono - Simple ETL in python 3.5+
Romain Dorgueil
 
Python profiling
Python profilingPython profiling
Python profiling
dreampuf
 
Simple Data Engineering in Python 3.5+ — Pycon.DE 2017 Karlsruhe — Bonobo ETL
Simple Data Engineering in Python 3.5+ — Pycon.DE 2017 Karlsruhe — Bonobo ETLSimple Data Engineering in Python 3.5+ — Pycon.DE 2017 Karlsruhe — Bonobo ETL
Simple Data Engineering in Python 3.5+ — Pycon.DE 2017 Karlsruhe — Bonobo ETL
Romain Dorgueil
 
Python for Scientific Computing -- Ricardo Cruz
Python for Scientific Computing -- Ricardo CruzPython for Scientific Computing -- Ricardo Cruz
Python for Scientific Computing -- Ricardo Cruz
rpmcruz
 
D vs OWKN Language at LLnagoya
D vs OWKN Language at LLnagoyaD vs OWKN Language at LLnagoya
D vs OWKN Language at LLnagoya
N Masahiro
 
TCO in Python via bytecode manipulation.
TCO in Python via bytecode manipulation.TCO in Python via bytecode manipulation.
TCO in Python via bytecode manipulation.
lnikolaeva
 
Metaprogramming and Reflection in Common Lisp
Metaprogramming and Reflection in Common LispMetaprogramming and Reflection in Common Lisp
Metaprogramming and Reflection in Common Lisp
Damien Cassou
 
Boost.Python: C++ and Python Integration
Boost.Python: C++ and Python IntegrationBoost.Python: C++ and Python Integration
Boost.Python: C++ and Python Integration
GlobalLogic Ukraine
 
Machine learning with py torch
Machine learning with py torchMachine learning with py torch
Machine learning with py torch
Riza Fahmi
 
Boost.Python - domesticating the snake
Boost.Python - domesticating the snakeBoost.Python - domesticating the snake
Boost.Python - domesticating the snake
Sławomir Zborowski
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Sergey Platonov
 
PyPy's approach to construct domain-specific language runtime
PyPy's approach to construct domain-specific language runtimePyPy's approach to construct domain-specific language runtime
PyPy's approach to construct domain-specific language runtime
National Cheng Kung University
 
What&rsquo;s new in Visual C++
What&rsquo;s new in Visual C++What&rsquo;s new in Visual C++
What&rsquo;s new in Visual C++
Microsoft
 
Memory efficient pytorch
Memory efficient pytorchMemory efficient pytorch
Memory efficient pytorch
Hyungjoo Cho
 
Simple ETL in python 3.5+ with Bonobo - PyParis 2017
Simple ETL in python 3.5+ with Bonobo - PyParis 2017Simple ETL in python 3.5+ with Bonobo - PyParis 2017
Simple ETL in python 3.5+ with Bonobo - PyParis 2017
Romain Dorgueil
 
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
it-people
 
Simple ETL in Python 3.5+ - PolyConf Paris 2017 - Lightning Talk (10 minutes)
Simple ETL in Python 3.5+ - PolyConf Paris 2017 - Lightning Talk (10 minutes)Simple ETL in Python 3.5+ - PolyConf Paris 2017 - Lightning Talk (10 minutes)
Simple ETL in Python 3.5+ - PolyConf Paris 2017 - Lightning Talk (10 minutes)
Romain Dorgueil
 
C++11 & C++14
C++11 & C++14C++11 & C++14
C++11 & C++14
CyberPlusIndia
 
Threads and Callbacks for Embedded Python
Threads and Callbacks for Embedded PythonThreads and Callbacks for Embedded Python
Threads and Callbacks for Embedded Python
Yi-Lung Tsai
 

What's hot (20)

GoLightly: Building VM-Based Language Runtimes with Google Go
GoLightly: Building VM-Based Language Runtimes with Google GoGoLightly: Building VM-Based Language Runtimes with Google Go
GoLightly: Building VM-Based Language Runtimes with Google Go
 
EuroPython 2017 - Bonono - Simple ETL in python 3.5+
EuroPython 2017 - Bonono - Simple ETL in python 3.5+EuroPython 2017 - Bonono - Simple ETL in python 3.5+
EuroPython 2017 - Bonono - Simple ETL in python 3.5+
 
Python profiling
Python profilingPython profiling
Python profiling
 
Simple Data Engineering in Python 3.5+ — Pycon.DE 2017 Karlsruhe — Bonobo ETL
Simple Data Engineering in Python 3.5+ — Pycon.DE 2017 Karlsruhe — Bonobo ETLSimple Data Engineering in Python 3.5+ — Pycon.DE 2017 Karlsruhe — Bonobo ETL
Simple Data Engineering in Python 3.5+ — Pycon.DE 2017 Karlsruhe — Bonobo ETL
 
Python for Scientific Computing -- Ricardo Cruz
Python for Scientific Computing -- Ricardo CruzPython for Scientific Computing -- Ricardo Cruz
Python for Scientific Computing -- Ricardo Cruz
 
D vs OWKN Language at LLnagoya
D vs OWKN Language at LLnagoyaD vs OWKN Language at LLnagoya
D vs OWKN Language at LLnagoya
 
TCO in Python via bytecode manipulation.
TCO in Python via bytecode manipulation.TCO in Python via bytecode manipulation.
TCO in Python via bytecode manipulation.
 
Metaprogramming and Reflection in Common Lisp
Metaprogramming and Reflection in Common LispMetaprogramming and Reflection in Common Lisp
Metaprogramming and Reflection in Common Lisp
 
Boost.Python: C++ and Python Integration
Boost.Python: C++ and Python IntegrationBoost.Python: C++ and Python Integration
Boost.Python: C++ and Python Integration
 
Machine learning with py torch
Machine learning with py torchMachine learning with py torch
Machine learning with py torch
 
Boost.Python - domesticating the snake
Boost.Python - domesticating the snakeBoost.Python - domesticating the snake
Boost.Python - domesticating the snake
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
 
PyPy's approach to construct domain-specific language runtime
PyPy's approach to construct domain-specific language runtimePyPy's approach to construct domain-specific language runtime
PyPy's approach to construct domain-specific language runtime
 
What&rsquo;s new in Visual C++
What&rsquo;s new in Visual C++What&rsquo;s new in Visual C++
What&rsquo;s new in Visual C++
 
Memory efficient pytorch
Memory efficient pytorchMemory efficient pytorch
Memory efficient pytorch
 
Simple ETL in python 3.5+ with Bonobo - PyParis 2017
Simple ETL in python 3.5+ with Bonobo - PyParis 2017Simple ETL in python 3.5+ with Bonobo - PyParis 2017
Simple ETL in python 3.5+ with Bonobo - PyParis 2017
 
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
 
Simple ETL in Python 3.5+ - PolyConf Paris 2017 - Lightning Talk (10 minutes)
Simple ETL in Python 3.5+ - PolyConf Paris 2017 - Lightning Talk (10 minutes)Simple ETL in Python 3.5+ - PolyConf Paris 2017 - Lightning Talk (10 minutes)
Simple ETL in Python 3.5+ - PolyConf Paris 2017 - Lightning Talk (10 minutes)
 
C++11 & C++14
C++11 & C++14C++11 & C++14
C++11 & C++14
 
Threads and Callbacks for Embedded Python
Threads and Callbacks for Embedded PythonThreads and Callbacks for Embedded Python
Threads and Callbacks for Embedded Python
 

Similar to «Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies

Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPythonByterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
akaptur
 
Pydiomatic
PydiomaticPydiomatic
Pydiomatic
rik0
 
Python idiomatico
Python idiomaticoPython idiomatico
Python idiomatico
PyCon Italia
 
Profiling and optimization
Profiling and optimizationProfiling and optimization
Profiling and optimizationg3_nittala
 
Music as data
Music as dataMusic as data
Music as data
John Vlachoyiannis
 
app4.pptx
app4.pptxapp4.pptx
app4.pptx
sg4795
 
Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with Scalapramode_ce
 
Cluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in CCluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in C
Steffen Wenz
 
Python basic
Python basicPython basic
Python basic
Saifuddin Kaijar
 
Haskell retrospective
Haskell retrospectiveHaskell retrospective
Haskell retrospectivechenge2k
 
обзор Python
обзор Pythonобзор Python
обзор Python
Yehor Nazarkin
 
Ankara Jug - Practical Functional Programming with Scala
Ankara Jug - Practical Functional Programming with ScalaAnkara Jug - Practical Functional Programming with Scala
Ankara Jug - Practical Functional Programming with Scala
Ensar Basri Kahveci
 
GE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python ProgrammingGE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python Programming
Muthu Vinayagam
 
Danny Adair - Python Cookbook - Intro
Danny Adair - Python Cookbook - IntroDanny Adair - Python Cookbook - Intro
Danny Adair - Python Cookbook - Intro
danny.adair
 
Object Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonObject Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in Python
Python Ireland
 
Scala as a Declarative Language
Scala as a Declarative LanguageScala as a Declarative Language
Scala as a Declarative Language
vsssuresh
 
Hands on lua
Hands on luaHands on lua
Hands on lua
Javier Arauz
 
Swift for tensorflow
Swift for tensorflowSwift for tensorflow
Swift for tensorflow
규영 허
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
Prashant Kalkar
 

Similar to «Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies (20)

Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPythonByterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
 
Pydiomatic
PydiomaticPydiomatic
Pydiomatic
 
Python idiomatico
Python idiomaticoPython idiomatico
Python idiomatico
 
Profiling and optimization
Profiling and optimizationProfiling and optimization
Profiling and optimization
 
Music as data
Music as dataMusic as data
Music as data
 
app4.pptx
app4.pptxapp4.pptx
app4.pptx
 
Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with Scala
 
Cluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in CCluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in C
 
Python basic
Python basicPython basic
Python basic
 
Haskell retrospective
Haskell retrospectiveHaskell retrospective
Haskell retrospective
 
обзор Python
обзор Pythonобзор Python
обзор Python
 
Ankara Jug - Practical Functional Programming with Scala
Ankara Jug - Practical Functional Programming with ScalaAnkara Jug - Practical Functional Programming with Scala
Ankara Jug - Practical Functional Programming with Scala
 
GE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python ProgrammingGE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python Programming
 
effective_r27
effective_r27effective_r27
effective_r27
 
Danny Adair - Python Cookbook - Intro
Danny Adair - Python Cookbook - IntroDanny Adair - Python Cookbook - Intro
Danny Adair - Python Cookbook - Intro
 
Object Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonObject Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in Python
 
Scala as a Declarative Language
Scala as a Declarative LanguageScala as a Declarative Language
Scala as a Declarative Language
 
Hands on lua
Hands on luaHands on lua
Hands on lua
 
Swift for tensorflow
Swift for tensorflowSwift for tensorflow
Swift for tensorflow
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
 

More from it-people

«Про аналитику и серебряные пули» Александр Подсобляев, Rambler&Co
«Про аналитику и серебряные пули» Александр Подсобляев, Rambler&Co«Про аналитику и серебряные пули» Александр Подсобляев, Rambler&Co
«Про аналитику и серебряные пули» Александр Подсобляев, Rambler&Co
it-people
 
«Scrapy internals» Александр Сибиряков, Scrapinghub
«Scrapy internals» Александр Сибиряков, Scrapinghub«Scrapy internals» Александр Сибиряков, Scrapinghub
«Scrapy internals» Александр Сибиряков, Scrapinghub
it-people
 
«Gevent — быть или не быть?» Александр Мокров, Positive Technologies
«Gevent — быть или не быть?» Александр Мокров, Positive Technologies«Gevent — быть или не быть?» Александр Мокров, Positive Technologies
«Gevent — быть или не быть?» Александр Мокров, Positive Technologies
it-people
 
«Ещё один Поиск Яндекса» Александр Кошелев, Яндекс
«Ещё один Поиск Яндекса» Александр Кошелев, Яндекс«Ещё один Поиск Яндекса» Александр Кошелев, Яндекс
«Ещё один Поиск Яндекса» Александр Кошелев, Яндекс
it-people
 
«How I Learned to Stop Worrying and Love the BFG: нагрузочное тестирование со...
«How I Learned to Stop Worrying and Love the BFG: нагрузочное тестирование со...«How I Learned to Stop Worrying and Love the BFG: нагрузочное тестирование со...
«How I Learned to Stop Worrying and Love the BFG: нагрузочное тестирование со...
it-people
 
«Write once run anywhere — почём опиум для народа?» Игорь Новиков, Scalr
«Write once run anywhere — почём опиум для народа?» Игорь Новиков, Scalr«Write once run anywhere — почём опиум для народа?» Игорь Новиков, Scalr
«Write once run anywhere — почём опиум для народа?» Игорь Новиков, Scalr
it-people
 
«Gensim — тематическое моделирование для людей» Иван Меньших, Лев Константино...
«Gensim — тематическое моделирование для людей» Иван Меньших, Лев Константино...«Gensim — тематическое моделирование для людей» Иван Меньших, Лев Константино...
«Gensim — тематическое моделирование для людей» Иван Меньших, Лев Константино...
it-people
 
«Тотальный контроль производительности» Михаил Юматов, ЦИАН
«Тотальный контроль производительности» Михаил Юматов, ЦИАН«Тотальный контроль производительности» Михаил Юматов, ЦИАН
«Тотальный контроль производительности» Михаил Юматов, ЦИАН
it-people
 
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк
it-people
 
«Микросервисы наносят ответный удар!» Олег Чуркин, Rambler&Co
«Микросервисы наносят ответный удар!» Олег Чуркин, Rambler&Co«Микросервисы наносят ответный удар!» Олег Чуркин, Rambler&Co
«Микросервисы наносят ответный удар!» Олег Чуркин, Rambler&Co
it-people
 
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
it-people
 
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...
it-people
 
«PyWat. А хорошо ли вы знаете Python?» Александр Швец, Marilyn System
«PyWat. А хорошо ли вы знаете Python?» Александр Швец, Marilyn System«PyWat. А хорошо ли вы знаете Python?» Александр Швец, Marilyn System
«PyWat. А хорошо ли вы знаете Python?» Александр Швец, Marilyn System
it-people
 
«(Без)опасный Python», Иван Цыганов, Positive Technologies
«(Без)опасный Python», Иван Цыганов, Positive Technologies«(Без)опасный Python», Иван Цыганов, Positive Technologies
«(Без)опасный Python», Иван Цыганов, Positive Technologies
it-people
 
«Python of Things», Кирилл Борисов, Яндекс
«Python of Things», Кирилл Борисов, Яндекс«Python of Things», Кирилл Борисов, Яндекс
«Python of Things», Кирилл Борисов, Яндекс
it-people
 
«Как сделать так, чтобы тесты на Swift не причиняли боль» Сычев Александр, Ra...
«Как сделать так, чтобы тесты на Swift не причиняли боль» Сычев Александр, Ra...«Как сделать так, чтобы тесты на Swift не причиняли боль» Сычев Александр, Ra...
«Как сделать так, чтобы тесты на Swift не причиняли боль» Сычев Александр, Ra...
it-people
 
«Клиенту и серверу нужно поговорить» Прокопов Никита, Cognician
«Клиенту и серверу нужно поговорить» Прокопов Никита, Cognician«Клиенту и серверу нужно поговорить» Прокопов Никита, Cognician
«Клиенту и серверу нужно поговорить» Прокопов Никита, Cognician
it-people
 
«Кошелек или деньги: сложный выбор между памятью и процессором» Алексеенко Иг...
«Кошелек или деньги: сложный выбор между памятью и процессором» Алексеенко Иг...«Кошелек или деньги: сложный выбор между памятью и процессором» Алексеенко Иг...
«Кошелек или деньги: сложный выбор между памятью и процессором» Алексеенко Иг...
it-people
 
ЗАВИСИМОСТИ В КОМПОНЕНТНОМ ВЕБЕ, ПРИГОТОВЛЕННЫЕ ПРАВИЛЬНО, Гриненко Владимир,...
ЗАВИСИМОСТИ В КОМПОНЕНТНОМ ВЕБЕ, ПРИГОТОВЛЕННЫЕ ПРАВИЛЬНО, Гриненко Владимир,...ЗАВИСИМОСТИ В КОМПОНЕНТНОМ ВЕБЕ, ПРИГОТОВЛЕННЫЕ ПРАВИЛЬНО, Гриненко Владимир,...
ЗАВИСИМОСТИ В КОМПОНЕНТНОМ ВЕБЕ, ПРИГОТОВЛЕННЫЕ ПРАВИЛЬНО, Гриненко Владимир,...
it-people
 
ПРАКТИЧЕСКИЙ ОПЫТ ИСПОЛЬЗОВАНИЯ REACT NATIVE + REDUX, Краснояров Станислав, R...
ПРАКТИЧЕСКИЙ ОПЫТ ИСПОЛЬЗОВАНИЯ REACT NATIVE + REDUX, Краснояров Станислав, R...ПРАКТИЧЕСКИЙ ОПЫТ ИСПОЛЬЗОВАНИЯ REACT NATIVE + REDUX, Краснояров Станислав, R...
ПРАКТИЧЕСКИЙ ОПЫТ ИСПОЛЬЗОВАНИЯ REACT NATIVE + REDUX, Краснояров Станислав, R...
it-people
 

More from it-people (20)

«Про аналитику и серебряные пули» Александр Подсобляев, Rambler&Co
«Про аналитику и серебряные пули» Александр Подсобляев, Rambler&Co«Про аналитику и серебряные пули» Александр Подсобляев, Rambler&Co
«Про аналитику и серебряные пули» Александр Подсобляев, Rambler&Co
 
«Scrapy internals» Александр Сибиряков, Scrapinghub
«Scrapy internals» Александр Сибиряков, Scrapinghub«Scrapy internals» Александр Сибиряков, Scrapinghub
«Scrapy internals» Александр Сибиряков, Scrapinghub
 
«Gevent — быть или не быть?» Александр Мокров, Positive Technologies
«Gevent — быть или не быть?» Александр Мокров, Positive Technologies«Gevent — быть или не быть?» Александр Мокров, Positive Technologies
«Gevent — быть или не быть?» Александр Мокров, Positive Technologies
 
«Ещё один Поиск Яндекса» Александр Кошелев, Яндекс
«Ещё один Поиск Яндекса» Александр Кошелев, Яндекс«Ещё один Поиск Яндекса» Александр Кошелев, Яндекс
«Ещё один Поиск Яндекса» Александр Кошелев, Яндекс
 
«How I Learned to Stop Worrying and Love the BFG: нагрузочное тестирование со...
«How I Learned to Stop Worrying and Love the BFG: нагрузочное тестирование со...«How I Learned to Stop Worrying and Love the BFG: нагрузочное тестирование со...
«How I Learned to Stop Worrying and Love the BFG: нагрузочное тестирование со...
 
«Write once run anywhere — почём опиум для народа?» Игорь Новиков, Scalr
«Write once run anywhere — почём опиум для народа?» Игорь Новиков, Scalr«Write once run anywhere — почём опиум для народа?» Игорь Новиков, Scalr
«Write once run anywhere — почём опиум для народа?» Игорь Новиков, Scalr
 
«Gensim — тематическое моделирование для людей» Иван Меньших, Лев Константино...
«Gensim — тематическое моделирование для людей» Иван Меньших, Лев Константино...«Gensim — тематическое моделирование для людей» Иван Меньших, Лев Константино...
«Gensim — тематическое моделирование для людей» Иван Меньших, Лев Константино...
 
«Тотальный контроль производительности» Михаил Юматов, ЦИАН
«Тотальный контроль производительности» Михаил Юматов, ЦИАН«Тотальный контроль производительности» Михаил Юматов, ЦИАН
«Тотальный контроль производительности» Михаил Юматов, ЦИАН
 
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк
 
«Микросервисы наносят ответный удар!» Олег Чуркин, Rambler&Co
«Микросервисы наносят ответный удар!» Олег Чуркин, Rambler&Co«Микросервисы наносят ответный удар!» Олег Чуркин, Rambler&Co
«Микросервисы наносят ответный удар!» Олег Чуркин, Rambler&Co
 
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
 
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...
 
«PyWat. А хорошо ли вы знаете Python?» Александр Швец, Marilyn System
«PyWat. А хорошо ли вы знаете Python?» Александр Швец, Marilyn System«PyWat. А хорошо ли вы знаете Python?» Александр Швец, Marilyn System
«PyWat. А хорошо ли вы знаете Python?» Александр Швец, Marilyn System
 
«(Без)опасный Python», Иван Цыганов, Positive Technologies
«(Без)опасный Python», Иван Цыганов, Positive Technologies«(Без)опасный Python», Иван Цыганов, Positive Technologies
«(Без)опасный Python», Иван Цыганов, Positive Technologies
 
«Python of Things», Кирилл Борисов, Яндекс
«Python of Things», Кирилл Борисов, Яндекс«Python of Things», Кирилл Борисов, Яндекс
«Python of Things», Кирилл Борисов, Яндекс
 
«Как сделать так, чтобы тесты на Swift не причиняли боль» Сычев Александр, Ra...
«Как сделать так, чтобы тесты на Swift не причиняли боль» Сычев Александр, Ra...«Как сделать так, чтобы тесты на Swift не причиняли боль» Сычев Александр, Ra...
«Как сделать так, чтобы тесты на Swift не причиняли боль» Сычев Александр, Ra...
 
«Клиенту и серверу нужно поговорить» Прокопов Никита, Cognician
«Клиенту и серверу нужно поговорить» Прокопов Никита, Cognician«Клиенту и серверу нужно поговорить» Прокопов Никита, Cognician
«Клиенту и серверу нужно поговорить» Прокопов Никита, Cognician
 
«Кошелек или деньги: сложный выбор между памятью и процессором» Алексеенко Иг...
«Кошелек или деньги: сложный выбор между памятью и процессором» Алексеенко Иг...«Кошелек или деньги: сложный выбор между памятью и процессором» Алексеенко Иг...
«Кошелек или деньги: сложный выбор между памятью и процессором» Алексеенко Иг...
 
ЗАВИСИМОСТИ В КОМПОНЕНТНОМ ВЕБЕ, ПРИГОТОВЛЕННЫЕ ПРАВИЛЬНО, Гриненко Владимир,...
ЗАВИСИМОСТИ В КОМПОНЕНТНОМ ВЕБЕ, ПРИГОТОВЛЕННЫЕ ПРАВИЛЬНО, Гриненко Владимир,...ЗАВИСИМОСТИ В КОМПОНЕНТНОМ ВЕБЕ, ПРИГОТОВЛЕННЫЕ ПРАВИЛЬНО, Гриненко Владимир,...
ЗАВИСИМОСТИ В КОМПОНЕНТНОМ ВЕБЕ, ПРИГОТОВЛЕННЫЕ ПРАВИЛЬНО, Гриненко Владимир,...
 
ПРАКТИЧЕСКИЙ ОПЫТ ИСПОЛЬЗОВАНИЯ REACT NATIVE + REDUX, Краснояров Станислав, R...
ПРАКТИЧЕСКИЙ ОПЫТ ИСПОЛЬЗОВАНИЯ REACT NATIVE + REDUX, Краснояров Станислав, R...ПРАКТИЧЕСКИЙ ОПЫТ ИСПОЛЬЗОВАНИЯ REACT NATIVE + REDUX, Краснояров Станислав, R...
ПРАКТИЧЕСКИЙ ОПЫТ ИСПОЛЬЗОВАНИЯ REACT NATIVE + REDUX, Краснояров Станислав, R...
 

Recently uploaded

Living-in-IT-era-Module-7-Imaging-and-Design-for-Social-Impact.pptx
Living-in-IT-era-Module-7-Imaging-and-Design-for-Social-Impact.pptxLiving-in-IT-era-Module-7-Imaging-and-Design-for-Social-Impact.pptx
Living-in-IT-era-Module-7-Imaging-and-Design-for-Social-Impact.pptx
TristanJasperRamos
 
Latest trends in computer networking.pptx
Latest trends in computer networking.pptxLatest trends in computer networking.pptx
Latest trends in computer networking.pptx
JungkooksNonexistent
 
ER(Entity Relationship) Diagram for online shopping - TAE
ER(Entity Relationship) Diagram for online shopping - TAEER(Entity Relationship) Diagram for online shopping - TAE
ER(Entity Relationship) Diagram for online shopping - TAE
Himani415946
 
This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!
nirahealhty
 
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
3ipehhoa
 
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and GuidelinesMulti-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Sanjeev Rampal
 
test test test test testtest test testtest test testtest test testtest test ...
test test  test test testtest test testtest test testtest test testtest test ...test test  test test testtest test testtest test testtest test testtest test ...
test test test test testtest test testtest test testtest test testtest test ...
Arif0071
 
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
3ipehhoa
 
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shopHistory+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
laozhuseo02
 
How to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptxHow to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptx
Gal Baras
 
1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...
JeyaPerumal1
 
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
3ipehhoa
 
BASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptxBASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptx
natyesu
 
Output determination SAP S4 HANA SAP SD CC
Output determination SAP S4 HANA SAP SD CCOutput determination SAP S4 HANA SAP SD CC
Output determination SAP S4 HANA SAP SD CC
ShahulHameed54211
 
The+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptxThe+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptx
laozhuseo02
 
guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...
Rogerio Filho
 

Recently uploaded (16)

Living-in-IT-era-Module-7-Imaging-and-Design-for-Social-Impact.pptx
Living-in-IT-era-Module-7-Imaging-and-Design-for-Social-Impact.pptxLiving-in-IT-era-Module-7-Imaging-and-Design-for-Social-Impact.pptx
Living-in-IT-era-Module-7-Imaging-and-Design-for-Social-Impact.pptx
 
Latest trends in computer networking.pptx
Latest trends in computer networking.pptxLatest trends in computer networking.pptx
Latest trends in computer networking.pptx
 
ER(Entity Relationship) Diagram for online shopping - TAE
ER(Entity Relationship) Diagram for online shopping - TAEER(Entity Relationship) Diagram for online shopping - TAE
ER(Entity Relationship) Diagram for online shopping - TAE
 
This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!
 
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
 
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and GuidelinesMulti-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
 
test test test test testtest test testtest test testtest test testtest test ...
test test  test test testtest test testtest test testtest test testtest test ...test test  test test testtest test testtest test testtest test testtest test ...
test test test test testtest test testtest test testtest test testtest test ...
 
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
 
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shopHistory+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
 
How to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptxHow to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptx
 
1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...
 
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
 
BASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptxBASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptx
 
Output determination SAP S4 HANA SAP SD CC
Output determination SAP S4 HANA SAP SD CCOutput determination SAP S4 HANA SAP SD CC
Output determination SAP S4 HANA SAP SD CC
 
The+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptxThe+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptx
 
guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...
 

«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies

  • 1. { "talk": { "title": "Python on the edge of a razor", "event_id": "PyConRu_2017", }, "speaker": { "__qname__" : "Aleksandr Koshkin", "linkedin" : "lnkfy.com/7Do", "github" : "/magniff", } }
  • 2. Rather weird talk on performance
  • 3. def interprete(): while True: age = int(input('age: >> ')) # opcode, kind of # handlers if age < 6: print("Ahh %s, Who is a little cutie?" % age) elif age < 23: print( "So, %s ha? How is your school today?" % age ) else: print("Go find a job, you hippie!1") Is it just me, or...
  • 4. - Frame represents running code - Code represents instructions and interface for context PyObject * PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) { co = f->f_code; for (;;) { switch (opcode) { TARGET(LOAD_FAST) {* implementation of LOAD_FAST *} TARGET(LOAD_CONST) {* implementation of LOAD_CONST *} TARGET(STORE_FAST) {* implementation of STORE_FAST *} ... } } Frame evaluator
  • 5. TARGET(BINARY_ADD) { PyObject *right = POP(); PyObject *left = TOP(); PyObject *sum; ... sum = PyNumber_Add(left, right); ... DISPATCH(); } C API
  • 6. Years of awkward optimisations
  • 7. >>> def fib(a, b): while True: a, b = b, a+b yield b >>> f = fib(1, 1) >>> next(f) 2 >>> next(f) 3 >>> next(f) 5 >>> next(f) 8 Fibonacci generator
  • 8. >>> dis.dis(fib) 2 0 SETUP_LOOP 26 (to 29) -------------------------------------------------------------- 3 >> 3 LOAD_FAST 1 (b) 6 LOAD_FAST 0 (a) 9 LOAD_FAST 1 (b) 12 BINARY_ADD 13 ROT_TWO 14 STORE_FAST 0 (a) 17 STORE_FAST 1 (b) 4 20 LOAD_FAST 1 (b) 23 YIELD_VALUE 24 POP_TOP 25 JUMP_ABSOLUTE 3 What CPython generates
  • 9. from cocode import CodeObjectProxy, Constant, Return, Add code_proxy = CodeObjectProxy( Constant("Hello "), Constant("world!"), Add(), Return() ) code = code_proxy.assemble() assert eval(code) == "Hello world!" CoCode(https://github.com/magniff/cocode)
  • 10. def fibonacci(a, b): pass fib_asm_code = CodeObjectProxy( VariableFast('a'), VariableFast('b'), # -------------------------------------- Label(Dup(), "loop"), Rot3(), Add(), Dup(), Yield(), Pop(), Jump("loop"), interface=fibonacci, ) Fibonacci generator, cocode version
  • 11. >>> dis.dis(fibonacci) 0 0 LOAD_FAST 0 (a) 3 LOAD_FAST 1 (b) -------------------------------------------------------------- >> 6 DUP_TOP 7 ROT_THREE 8 BINARY_ADD 9 DUP_TOP 10 YIELD_VALUE 11 POP_TOP 12 JUMP_ABSOLUTE 6 # so, the algorithm is # a,b -> a,b,b -> b,a,b -> b,a+b -> b,a+b,a+b -> yield a+b and loop back Using stack machine like a pro
  • 12. Dit it help? $ time python fib.py real 0m0.449s $ time python fib_asm.py real 0m0.462s
  • 14. PyPy is fast because it is jitted, ok? This answer does not satisfy me
  • 15. late binding boxing vm overhead Deadly sins of dynamic programming languages
  • 16. some_method = some_object.method for value in huge_list: some_method(value) Late binding:
  • 18. We dont really see it, yet it is there VM overhead
  • 19. - negative Is this the end, mommy?
  • 20. Example: Say you are asked to sort one billion numbers, what you gonna do? The key to performance is specialization
  • 21. ● PyPy: yet another python implementation (fastest on market, though) ● PyPy is written in RPython - turbo ugly subset of python language ● You might think: hmmm, Python, even restricted one - that sounds fun ● It is not, trust me Before we start: RPython, PyPy etc.
  • 22. ● PyPy: yet another python implementation (fastest on market, though) ● PyPy is written in RPython - turbo ugly subset of python language ● You might think: hmmm, Python, even restricted one - that sounds fun ● It is not, trust me $ cat demo.py import os def main(argv): os.write(1, 'Is that even legal?n') return 0 def target(*args): return main, None Before we start: RPython, PyPy etc.
  • 23. $ python2 rpython/bin/rpython -O2 demo.py Before we start: RPython, PyPy etc.
  • 24.
  • 25. $ ./demo-c Is that even legal? Before we start: RPython, PyPy etc.
  • 26. [Timer] Timings: [Timer] annotate --- 3.6 s [Timer] rtype_lltype --- 0.1 s [Timer] backendopt_lltype --- 0.1 s [Timer] stackcheckinsertion_lltype --- 0.0 s [Timer] database_c --- 8.5 s [Timer] source_c --- 0.9 s [Timer] compile_c --- 1.8 s [Timer] ========================================= [Timer] Total: --- 15.0 s Before we start: RPython, PyPy etc.
  • 27. By Davide Ancona, Carl Friedrich Bolz, Antonio Cuni, and Armin Rigo Automatic generation of JIT compilers for dynamic languages in .NET Я испытал мощный эмоциональный подъем
  • 28. By Yoshihiko Futamura Having program P, taking inputs s1 ...sn and d1 ...dm S(P, (s1 ,..., sm )) = P’ Produce program P’ such as P(s1 ...sn , d1 ,..., dm ) = P’(d1 ,..., dm ) Partial Evaluation of Computation Process, Revisited
  • 29. S(P, (s1 , ..., sm )) = P’
  • 32. Specialization level. (since it is too static) Classical partial evaluation has a disadvantage
  • 33. So, we better obtain more info at runtime. (Tempo, DyC) Classical partial evaluation has a disadvantage
  • 34. Yes! Can we go fully dynamic?
  • 36. – Stack manipulation: POP, PUSHARG, SWAP, etc. – Flow control: BR_COND, BR jumps. – Arithmetic: ADD, SUB, etc. – Comparisons: EQ, LT, GT, etc. – Object-oriented operations: NEW, GETATTR, SETATTR. – List operations: CONS, CAR, CDR. TLC language (rpython/jit/tl/tlc.py)
  • 37. def interp_eval(code, pc, args, pool): code_len = len(code) stack = [] while pc < code_len: opcode = ord(code[pc]) pc += 1 if opcode == PUSH: stack.append(IntObj(char2int(code[pc]))) pc += 1 elif opcode == PUSHARG: stack.append (args[0]) elif opcode == SUB: a, b = stack.pop(), stack.pop() stack.append(b.sub(a)) elif opcode == LT: a, b = stack.pop(), stack.pop() stack.append(IntObj(b.lt(a))) elif opcode == BR_COND: cond = stack.pop() if cond.istrue(): pc += char2int(code[pc]) pc += 1 elif opcode == RETURN: break ... return stack[-1]
  • 38. class IntObj(Obj): def __init__(self, value): self.value = value def lt(self, other): return self.value < other.int_o() def sub(self, other): return IntObj(self.value - other.int_o()) def int_o(self): return self.value
  • 39. main: PUSHARG PUSH 0 LT BR_COND neg pos: PUSHARG RETURN neg: PUSH 0 PUSHARG SUB RETURN Say we are provided with the following code
  • 40. Not much. What static partial evaluator can do?
  • 41. def interp_eval(code, pc, args, pool): code_len = len(code) stack = [] while pc < code_len: opcode = ord(code[pc]) pc += 1 if opcode == PUSH: stack.append(IntObj(char2int(code[pc]))) pc += 1 elif opcode == PUSHARG: stack.append (args[0]) elif opcode == SUB: a, b = stack.pop(), stack.pop() stack.append(b.sub(a)) elif opcode == LT: a, b = stack.pop(), stack.pop() stack.append(IntObj(b.lt(a))) elif opcode == BR_COND: cond = stack.pop() if cond.istrue(): pc += char2int(code[pc]) pc += 1 elif opcode == RETURN: break ... return stack[-1]
  • 42. def interp_eval_abs(args): stack = [] stack.append(args[0]) stack.append(IntObj(0)) a, b = stack.pop(), stack.pop() stack.append(IntObj(b.lt(a))) cond = stack.pop() if cond.istrue(): stack.append(args[0]) return stack[-1] else: stack.append(IntObj(0)) stack.append(args[0]) a, b = stack.pop(), stack.pop() stack.append(b.sub(a)) return stack[-1]
  • 44. def interp_eval_abs(args): stack = [] stack.append(args[0]) stack.append(IntObj(0)) a, b = stack.pop(), stack.pop() stack.append(IntObj(b.lt(a))) cond = stack.pop() if cond.istrue(): stack.append(args[0]) return stack[-1] # 0_o else: stack.append(IntObj(0)) stack.append(args[0]) a, b = stack.pop(), stack.pop() stack.append(b.sub(a)) return stack[-1] # 0_o
  • 45. def interp_eval_abs(args): v0 = args[0] v1 = IntObj(0) a, b = v0, v1 v0 = IntObj(b.lt(a)) cond = v0 if cond.istrue(): v0 = args[0] return v0 else: v0 = IntObj(0) v1 = args[0] a, b = v0, v1 v0 = b.sub(a) return v0
  • 46. def interp_eval_abs(args): a = args[0] cls_a = a.__class__ switch cls_a : IntObj : if 0 < a.value: return a else: return IntObj(0 - a.value ) default: try_something_else()
  • 47. But does this make any sense?
  • 49. ● Apply S function only to hot loops ● Lots of consequent iterations of the loop take the same path in the CFG Oook, but the hottest loop in the interpreter is a opcode dispatch loop. Assumptions:
  • 50. Metatracer Approach (a approach, not the approach):
  • 51. Automatic handling of such a problems is extremely difficult task. How about providing a set of hints? But still:
  • 52. myjitdriver = JitDriver(greens = ['pc', 'code'], reds = ['frame', 'pool']) def interp_eval(code, pc, args, pool): code_len = len(code) stack = [] frame = Frame(args, pc) while pc < code_len: myjitdriver.jit_merge_point( frame=frame, code=code, pc=pc, pool=pool ) opcode = ord(code[pc]) pc += 1 if opcode == some_opcode: ... elif opcode == BR: old_pc = pc pc += char2int(code[pc]) + 1 if old_pc > pc: myjitdriver.can_enter_jit( code=code, pc=pc, frame=frame, pool=pool ) return stack[-1]
  • 53. def lookup(cls, methname): ... def call_method(obj, method_name, arguments): cls = obj.getclass() ... method = lookup(cls, method_name) return method.call(obj, arguments)
  • 54. @elidable def lookup(cls, methname): ... def call_method(obj, method_name, arguments): cls = obj.getclass() promote(cls) method = lookup(cls, method_name) return method.call(obj, arguments) Somewhat similar to PIC
  • 55. No, thanks Any details to metajit in this talk?
  • 56. :3