WEBVTT

00:00:00.001 --> 00:00:02.220
Is your Python code running a little slow?

00:00:02.220 --> 00:00:06.540
Did you know the PyPy runtime could make it run up to 10 times faster?

00:00:06.540 --> 00:00:07.420
Seriously.

00:00:07.420 --> 00:00:10.660
Maja Falkowski is here to tell us all about it.

00:00:10.660 --> 00:00:16.120
This is episode number 21, recorded Wednesday, July 8th, 2015.

00:00:16.120 --> 00:00:19.700
Developers, developers, developers, developers.

00:00:19.700 --> 00:00:25.000
I'm a developer in many senses of the word because I make these applications, but I also

00:00:25.000 --> 00:00:27.220
use these verbs to make this music.

00:00:27.220 --> 00:00:31.760
I construct it line by line, just like when I'm coding another software design.

00:00:31.760 --> 00:00:34.980
In both cases, it's about design patterns.

00:00:34.980 --> 00:00:36.480
Anyone can get the job done.

00:00:36.480 --> 00:00:37.980
It's the execution that matters.

00:00:37.980 --> 00:00:39.460
I have many interests.

00:00:39.460 --> 00:00:45.640
Welcome to Talk Python To Me, a weekly podcast on Python, the language, the libraries, the

00:00:45.640 --> 00:00:47.240
ecosystem, and the personalities.

00:00:47.240 --> 00:00:49.280
This is your host, Michael Kennedy.

00:00:49.280 --> 00:00:51.720
Follow me on Twitter, where I'm @mkennedy.

00:00:51.720 --> 00:00:56.360
Keep up with the show and listen to past episodes at talkpython.fm.

00:00:56.360 --> 00:00:59.580
And follow the show on Twitter via at talkpython.

00:00:59.580 --> 00:01:05.760
This episode, we'll be talking with Maja Falkowski about the amazing alternative Python implementation,

00:01:05.760 --> 00:01:06.540
PyPy.

00:01:06.540 --> 00:01:10.900
This episode is brought to you by Hired and Codeship.

00:01:10.900 --> 00:01:15.060
Thank them for supporting the show via Twitter, where they're at hired underscore HQ,

00:01:15.160 --> 00:01:16.320
and at codechip.

00:01:16.320 --> 00:01:19.580
Before we get to Maja, let me share a little news with you.

00:01:19.580 --> 00:01:24.720
First off, Talk Python To Me has a new domain name, talkpython.fm.

00:01:24.720 --> 00:01:30.020
I put the idea of a shorter .fm-based domain out on Twitter, and I'd say about 80% of the

00:01:30.020 --> 00:01:32.600
listeners said they liked it better than the longer .com domain.

00:01:32.600 --> 00:01:33.920
So here you go.

00:01:34.680 --> 00:01:39.900
About a month ago, I moved all the MP3 file traffic out of Amazon S3 and into a dedicated

00:01:39.900 --> 00:01:41.860
audio file cache server.

00:01:41.860 --> 00:01:46.740
It's a lightweight Flask Python 3 app running through Nginx and Microwiskey.

00:01:47.240 --> 00:01:52.120
A few listeners expressed interest in seeing the code, so I did a little work to try to generalize

00:01:52.120 --> 00:01:53.800
this a bit, and I open sourced it.

00:01:53.800 --> 00:01:55.500
I'm calling the project Cachedier.

00:01:55.500 --> 00:02:00.160
And you can find a blog post as well as a link to the GitHub project on the show notes.

00:02:01.040 --> 00:02:03.640
Next up, we have a new Python podcast.

00:02:03.640 --> 00:02:11.000
I'm super happy to announce a Python podcast by Brian Okken called Python Test Podcast.

00:02:11.000 --> 00:02:16.000
You can find it at pythontesting.net slash category slash podcast.

00:02:16.000 --> 00:02:18.060
Now, let's get on to the show.

00:02:18.060 --> 00:02:19.340
Maja, welcome to the show.

00:02:19.340 --> 00:02:20.800
Thanks for inviting me.

00:02:20.800 --> 00:02:24.960
Yeah, I'm super excited to talk about our topic today, which is PyPy.

00:02:25.640 --> 00:02:32.060
And I think what you guys are doing with PyPy is so incredibly cool to be taking some of

00:02:32.060 --> 00:02:38.440
these JIT compilation GC sort of semi-compiled languages or concepts and applying them to

00:02:38.440 --> 00:02:38.760
Python.

00:02:38.760 --> 00:02:40.880
So really happy to talk about that.

00:02:40.880 --> 00:02:47.560
The story of compiling dynamic languages is really sort of old and half-forgotten.

00:02:47.560 --> 00:02:54.520
Like, we know these days that you can do this with JavaScript, but the original work on small

00:02:54.520 --> 00:03:02.440
talk dates back to at least mid-90s, if not earlier, which is what we are all building on

00:03:02.440 --> 00:03:03.420
top of anyway.

00:03:03.420 --> 00:03:05.580
So it's nothing new.

00:03:05.580 --> 00:03:07.840
The new part is just applying this to Python.

00:03:07.840 --> 00:03:09.040
That's right.

00:03:09.040 --> 00:03:09.580
That's right.

00:03:09.580 --> 00:03:11.480
Well, I think it's great.

00:03:11.480 --> 00:03:16.020
Maybe before we get into the details of what you guys are doing, maybe you could give the

00:03:16.020 --> 00:03:20.360
listeners who are not familiar with PyPy a little history and introduction to it.

00:03:21.080 --> 00:03:29.420
So PyPy is essentially a Python interpreter, which works very, very similarly to the normal

00:03:29.420 --> 00:03:34.080
thing that you would call Python, that technically is called CPython.

00:03:34.080 --> 00:03:35.840
It's a Python interpreter written in C.

00:03:35.840 --> 00:03:40.560
And we have a different Python interpreter, which is implemented slightly differently.

00:03:40.940 --> 00:03:48.380
And for the most part, glancing over all the details, it should run faster on most of the

00:03:48.380 --> 00:03:55.040
examples because it can dynamically compile Python down all the way to the assembler level.

00:03:55.040 --> 00:04:02.320
So it's like a normal Python interpreter, except sometimes faster, most times faster, in fact.

00:04:02.320 --> 00:04:03.700
That's it.

00:04:03.780 --> 00:04:07.360
It sounds very simple, but it's actually quite a big project.

00:04:07.360 --> 00:04:10.780
It has been around more or less 10 years by now.

00:04:10.780 --> 00:04:11.440
Wow.

00:04:11.440 --> 00:04:12.540
It started 10 years ago.

00:04:12.540 --> 00:04:14.040
And when did you get involved with it?

00:04:14.040 --> 00:04:18.080
I got involved, I think, 2006 or 2007.

00:04:19.020 --> 00:04:29.660
I was doing, I sort of got interested in Python static analysis, which PyPy, part of PyPy is doing

00:04:29.660 --> 00:04:35.080
that, is taking a restricted subset of Python, which PyPy is implemented in and compiling it

00:04:35.080 --> 00:04:35.920
down to the C level.

00:04:36.120 --> 00:04:42.700
So I was interested in Python static analysis and I glanced over PyPy project and sort of

00:04:42.700 --> 00:04:44.640
started getting involved.

00:04:44.640 --> 00:04:50.240
And then I got a spot at Google Summer of Code to work on PyPy for the summer.

00:04:50.240 --> 00:04:52.160
And that's essentially how it all started.

00:04:52.160 --> 00:04:55.700
How many people work on PyPy or contribute to PyPy?

00:04:55.700 --> 00:05:00.140
Depending how you count, it's anything between three and 30.

00:05:00.760 --> 00:05:09.420
PyPy is a big umbrella project for a vast variety of anything from, as I said, a Python interpreter

00:05:09.420 --> 00:05:15.940
to very researchy stuff that people at various universities try to experiment with.

00:05:15.940 --> 00:05:22.600
Like there is a couple of people working on running Python and PHP in the same process.

00:05:22.600 --> 00:05:29.720
So you run PHP code in the server, but you can still call Python functions in that process.

00:05:29.720 --> 00:05:33.400
There are people working on software transactional memory.

00:05:33.400 --> 00:05:39.580
So it's a big umbrella project that is a research vehicle for a lot of people, additionally to

00:05:39.580 --> 00:05:40.500
being the Python interpreter.

00:05:40.500 --> 00:05:45.320
Yeah, I can see how that would work for if you're doing some sort of academic research,

00:05:45.320 --> 00:05:48.500
especially something with JIT and GC, then it makes a lot of sense.

00:05:50.000 --> 00:05:54.860
I think one of the things that people either who are new to Python or have kind of dabbled

00:05:54.860 --> 00:06:00.300
in it, but are not, you know, deeply working with it and thinking about the internals of

00:06:00.300 --> 00:06:05.240
it every day, don't realize that there's actually a whole variety of different interpreters out

00:06:05.240 --> 00:06:05.540
there.

00:06:05.540 --> 00:06:06.960
There's a bunch.

00:06:07.360 --> 00:06:10.440
They're all slightly different.

00:06:10.440 --> 00:06:17.340
So let's glance over them because I think it's important to know there's like the CPython is

00:06:17.340 --> 00:06:22.620
the normal Python interpreter that is probably used by 99% of people using Python.

00:06:22.620 --> 00:06:23.300
Yeah.

00:06:23.300 --> 00:06:27.560
If I open up Linux or my Mac and I type the word Python and enter that's CPython, right?

00:06:27.560 --> 00:06:28.540
That's CPython.

00:06:28.540 --> 00:06:30.620
So that's what most people would use.

00:06:30.760 --> 00:06:36.280
CPython internals that you need to know is the fact that it's implemented in C.

00:06:36.280 --> 00:06:43.820
And another internal detail that's important to know is that it exposes the C API, which

00:06:43.820 --> 00:06:45.080
goes quite low.

00:06:45.080 --> 00:06:49.320
So it's possible to write C extensions in C for Python.

00:06:49.320 --> 00:06:54.440
So you write a bunch of C code, use a special API for accessing Python objects, and then it

00:06:54.440 --> 00:06:57.420
can be called from Python code, your C functions.

00:06:59.000 --> 00:07:04.340
Then we have Jiton, which is quite old, actually.

00:07:04.340 --> 00:07:11.900
And it's a Python interpreter written in Java and a similar project called Iron Python, which

00:07:11.900 --> 00:07:13.780
is a Python interpreter written in C#.

00:07:13.780 --> 00:07:22.380
And those two interpreters, they're quite widely used for people who write Java and want a better

00:07:22.380 --> 00:07:22.880
language.

00:07:22.880 --> 00:07:31.300
So they, so their main big advantage is integration with the underlying platform.

00:07:31.300 --> 00:07:35.600
So Jiton is very well integrated with Java and Iron Python with C#.

00:07:35.600 --> 00:07:40.440
So if you're writing C#, but you would really love to write some Python, you can do that these

00:07:40.440 --> 00:07:40.780
days.

00:07:40.780 --> 00:07:46.880
And then there's PyPy, which is another Python interpreter written slightly differently with

00:07:46.880 --> 00:07:47.960
a just-in-time compiler.

00:07:48.280 --> 00:07:50.760
So those are the four main interpreters.

00:07:50.760 --> 00:07:57.340
And there is, there is quite a few projects that try to enter this space, like PyStone, which

00:07:57.340 --> 00:08:00.740
is another Python interpreter written by Dropbox people.

00:08:00.980 --> 00:08:01.400
Yeah.

00:08:01.400 --> 00:08:07.620
I wanted to ask you about PyStone because that's, that seems to me to be somewhat similar to

00:08:07.620 --> 00:08:08.700
what you guys are doing.

00:08:08.700 --> 00:08:13.080
And, and it comes, the fact that it comes from Dropbox where Guido is and a lot, there's a

00:08:13.080 --> 00:08:17.960
lot of sort of gravity for the Python world at Dropbox that made it more interesting to me.

00:08:17.960 --> 00:08:21.580
Do you know anything about it or can you speak to how it compares or the goals or anything

00:08:21.580 --> 00:08:22.020
like that?

00:08:23.020 --> 00:08:28.480
So, well, I know that it's very, very similar to the project that once existed at Google

00:08:28.480 --> 00:08:29.680
called Unladen Swallow.

00:08:29.680 --> 00:08:38.200
So the main idea is that it's a Python interpreter that contains a just-in-time compiler that uses

00:08:38.200 --> 00:08:41.680
LLVM as the underlying assembler platform.

00:08:41.680 --> 00:08:42.860
Let's call it that way.

00:08:42.860 --> 00:08:44.800
And this is the main goal.

00:08:44.800 --> 00:08:46.280
The main goal is to run fast.

00:08:46.280 --> 00:08:50.960
Now, the current status is that it doesn't run fast.

00:08:50.960 --> 00:08:52.140
That's for sure.

00:08:52.140 --> 00:08:57.160
It runs roughly at the same speed as CPython for stuff that I've seen on their website.

00:08:57.160 --> 00:09:01.060
As for the future, I don't know.

00:09:01.060 --> 00:09:02.500
I really think the future is really hard.

00:09:02.500 --> 00:09:06.620
Especially when you don't have much visibility into it, right?

00:09:06.620 --> 00:09:07.660
Yeah.

00:09:07.660 --> 00:09:15.120
Like, I can tell you that like PyPy, PyPy has a bunch of different problems to PyStone.

00:09:15.120 --> 00:09:23.940
So, for example, we consciously choose to not implement the C API at first because the

00:09:23.940 --> 00:09:28.080
C API ties you a lot into the CPython model.

00:09:28.080 --> 00:09:31.040
We choose not to implement it at first.

00:09:31.040 --> 00:09:34.400
We implement it later as a compatibility layer.

00:09:34.400 --> 00:09:38.580
So the first problem is that it's quite slow.

00:09:38.580 --> 00:09:41.820
It's far, far slower than the one in CPython.

00:09:41.820 --> 00:09:48.040
And as far as I know, right now, Dropbox uses the same C API, which gives you a lot of problems,

00:09:48.040 --> 00:09:49.920
like a lot of constraints of your design.

00:09:51.460 --> 00:09:59.480
But also, like, gives you a huge, huge benefit, which is being able to use the same C modules, which are a huge part of the Python ecosystem.

00:10:00.280 --> 00:10:11.660
Yeah, especially some of the really powerful ones that people don't want to live without, things like NumPy and, to a lesser degree, SQLAlchemy, the things that have the C extensions that are really popular as well.

00:10:11.660 --> 00:10:13.500
So you guys don't want to miss out on that, right?

00:10:14.800 --> 00:10:15.160
Right.

00:10:15.160 --> 00:10:18.340
So you brought two interesting examples.

00:10:18.340 --> 00:10:24.800
So, for example, NumPy is so tied to the C API that it's very hard to avoid.

00:10:24.800 --> 00:10:27.020
It's not just NumPy.

00:10:27.020 --> 00:10:28.700
It's the entire ecosystem.

00:10:28.700 --> 00:10:37.480
We, in PyPy, we re-implemented most of NumPy, but we are still missing out on the entire ecosystem.

00:10:37.480 --> 00:10:47.140
And we have some stories how to approach that problem, but it's a hard problem to tackle, that we choose to make harder by not implementing the C API.

00:10:47.140 --> 00:10:50.820
However, for example, the SQLAlchemy stuff.

00:10:50.820 --> 00:10:53.140
SQLAlchemy is Python.

00:10:53.140 --> 00:11:00.820
It's not C, but it uses the database drivers, which are implemented in C, like a lot of them.

00:11:01.980 --> 00:11:08.380
So our answer to that is CFFI, which is a very, very simple way to call C from Python.

00:11:08.380 --> 00:11:12.280
And CFFI took off like crazy.

00:11:12.280 --> 00:11:31.540
Like, for most things, like database drivers, there's a CFFI-ready replacement that works as well and usually a lot better on PyPy that made it possible to use PyPy in places where you would normally not be able to do that.

00:11:31.540 --> 00:11:35.280
And CFFI is like really, really popular.

00:11:35.280 --> 00:11:39.200
It gets like over a million downloads a month, which is quite crazy.

00:11:39.200 --> 00:11:42.360
And CFFI is not just a PyPy thing.

00:11:42.360 --> 00:11:44.000
It also works in CPython, right?

00:11:44.000 --> 00:11:50.260
Yeah, it works in CPython in between like 2.6 and 3.something, I think.

00:11:50.260 --> 00:11:51.880
3.whatever is the latest.

00:11:51.880 --> 00:11:54.760
And it works on both PyPy and PyPy3.

00:11:54.760 --> 00:12:00.900
And since it's so simple, it will probably work one day in JITON too.

00:12:01.560 --> 00:12:07.720
You said you have a plan for the NumPy story and these other heavy sort of C-based ones.

00:12:07.720 --> 00:12:15.340
Currently, the way you support it, this is a question I don't know, is that you've kind of re-implemented a lot of it in Python?

00:12:15.340 --> 00:12:22.840
So we, to be precise, we re-implemented a lot of it in our Python.

00:12:22.840 --> 00:12:25.960
Our Python is the internal language that we use in PyPy.

00:12:26.220 --> 00:12:29.500
Right, that's the restricted Python that you guys actually target, right?

00:12:29.500 --> 00:12:30.020
Yes.

00:12:30.020 --> 00:12:35.140
Yeah, but we don't, generally don't encourage anybody to use it.

00:12:35.140 --> 00:12:38.180
Unless you're writing interpreters, then it's great.

00:12:38.180 --> 00:12:40.340
But if you're not writing interpreters, it's an awful language.

00:12:41.040 --> 00:12:56.020
But we, so the problem with NumPy is that NumPy ties so closely that we added special support in the JIT for parts of it and things like that, that we decided are important enough that you want to have them implement in the core of PyPy.

00:12:57.080 --> 00:13:01.540
So we have, most of NumPy actually works on PyPy.

00:13:01.540 --> 00:13:11.400
And this is sometimes not good enough because if you're using NumPy, chances are you're using SciPy, Scikit, Learn, Matplotlib, and all this stuff.

00:13:11.400 --> 00:13:23.140
We have some story how to use it, which is to, the simplest thing is just to embed the Python interpreter inside PyPy and call it using CFFI.

00:13:23.140 --> 00:13:24.260
It's a great hack.

00:13:24.260 --> 00:13:25.220
It works for us.

00:13:25.420 --> 00:13:25.900
Really?

00:13:25.900 --> 00:13:30.560
You can like fall back to regular Cpython within your PyPy app?

00:13:30.560 --> 00:13:33.280
Yeah, it's called PyMetabiosis.

00:13:33.280 --> 00:13:34.380
That's awesome.

00:13:34.380 --> 00:13:44.460
I'm pretty sure there's at least one video online with the author talking about it.

00:13:44.460 --> 00:13:49.180
It works great for the numeric stack, which is its goal.

00:13:49.180 --> 00:13:51.060
So this is our story.

00:13:51.060 --> 00:13:56.240
We are still raising funds to finish implementing NumPy.

00:13:56.240 --> 00:13:58.920
It says a very, very long tale of features.

00:13:58.920 --> 00:14:13.400
And once we are done with NumPy, we'll try to improve the story of calling other numeric libraries on top of PyPy to be able to mostly seamlessly be able to use stuff like SciPy and Matplotlib.

00:14:13.400 --> 00:14:15.140
It will still take a while.

00:14:15.140 --> 00:14:17.940
I'm not even willing to give an estimate.

00:14:17.940 --> 00:14:19.520
Sure.

00:14:19.520 --> 00:14:20.380
But it's great.

00:14:20.380 --> 00:14:21.980
And it does look like there's a lot of support there.

00:14:21.980 --> 00:14:26.940
We'll talk about that stuff in a little bit because I definitely want to call attention to that and let people know how they can help out.

00:14:27.940 --> 00:14:39.460
Before we get into those kind of details, though, can we talk just briefly about why would I use PyPy or when and why would I use PyPy over, say, CPython or Jython?

00:14:39.460 --> 00:14:41.500
Like, what do you guys excel at?

00:14:41.500 --> 00:14:46.080
When should a person out there is thinking, like, they've just realized, oh, my gosh, there's more than one interpreter?

00:14:46.080 --> 00:14:48.080
How do I choose?

00:14:48.180 --> 00:14:49.940
Like, can you help give some guidance around that?

00:14:49.940 --> 00:14:55.940
So typically, if you just discovered, oh, there's more than one interpreter, you just want to use CPython.

00:14:55.940 --> 00:14:57.460
That's like the simplest answer.

00:14:57.460 --> 00:15:04.280
You want to use CPython, but if you're writing an open source library, you want to support PyPy at least, which is what most people are doing.

00:15:04.280 --> 00:15:08.100
They're using CPython and the libraries support PyPy for the most part.

00:15:08.100 --> 00:15:14.480
Our typical user, and this is a very terrible description, but this is our typical user.

00:15:14.480 --> 00:15:27.140
This episode is brought to you by Hired.

00:15:27.140 --> 00:15:33.600
Hired is a two-sided, curated marketplace that connects the world's knowledge workers to the best opportunities.

00:15:33.600 --> 00:15:42.760
Each offer you receive has salary and equity presented right up front, and you can view the offers to accept or reject them before you even talk to the company.

00:15:43.260 --> 00:15:49.140
Typically, candidates receive five or more offers in just the first week, and there are no obligations, ever.

00:15:49.140 --> 00:15:51.220
Sounds pretty awesome, doesn't it?

00:15:51.220 --> 00:15:53.260
Well, did I mention there's a signing bonus?

00:15:53.260 --> 00:16:01.720
Everyone who accepts a job from Hired gets a $2,000 signing bonus, and as Talk Python listeners, it gets way sweeter.

00:16:01.720 --> 00:16:09.280
Use the link Hired.com slash Talk Python To Me, and Hired will double the signing bonus to $4,000.

00:16:10.180 --> 00:16:11.000
Opportunity's knocking.

00:16:11.000 --> 00:16:14.600
Visit Hired.com slash Talk Python To Me and answer the call.

00:16:14.600 --> 00:16:30.800
You have a large Python application that's spanning servers, serving millions of users,

00:16:30.800 --> 00:16:33.460
and you're running into corners.

00:16:33.460 --> 00:16:37.860
Like, you can't serve requests quickly enough.

00:16:37.860 --> 00:16:40.100
You can't serve enough users from machine.

00:16:40.100 --> 00:16:41.840
You're running into problems.

00:16:41.840 --> 00:16:48.920
Now, your application is too big to, say, rewrite it in C or Go, or it's just, like, too scary for whatever reason.

00:16:50.120 --> 00:16:54.900
So, you look, like, what it would take to run stuff in PyPy.

00:16:54.900 --> 00:17:06.160
It usually takes, like, a bit of, your code should run, but it usually takes a bit of effort to, like, see what sort of libraries do you use.

00:17:06.160 --> 00:17:07.600
Do you use NSE extensions?

00:17:07.600 --> 00:17:11.000
If their C extensions are, like, crucial, can you replace them with something?

00:17:11.660 --> 00:17:13.480
So, yeah, this is our typical user.

00:17:13.480 --> 00:17:18.460
And I have people, I run a consulting company that does that.

00:17:18.460 --> 00:17:22.640
There are people coming and asking, like, okay, I have this set up.

00:17:22.640 --> 00:17:25.940
It's impossible to do anything with it now.

00:17:25.940 --> 00:17:30.480
Can I just, like, swap the interpreters, make it run faster, and make the problems go away?

00:17:30.480 --> 00:17:31.980
This is our typical user.

00:17:33.660 --> 00:17:38.680
I hear why you described it that way is maybe not the best way, but, you know, you're right.

00:17:38.680 --> 00:17:44.920
If you have 100,000, half a million lines of Python, and really you just need to make it a little faster.

00:17:44.920 --> 00:17:49.140
If switching to a different interpreter like PyPy will solve that, that's great.

00:17:49.140 --> 00:17:53.600
So, speaking of faster, can you talk about the performance comparisons?

00:17:53.600 --> 00:17:57.400
I have a little example I'll tell you, but I'll let you go first.

00:17:57.400 --> 00:18:03.520
So, as usual, performance comparisons are usually very hard to do and flawed.

00:18:04.200 --> 00:18:05.520
Everybody, yes, absolutely.

00:18:05.520 --> 00:18:10.580
Everybody's thing they care about is not exactly what you're measuring, and so it might be totally misleading.

00:18:10.580 --> 00:18:12.000
But give it a shot.

00:18:12.000 --> 00:18:17.900
One good estimate is if you don't have benchmarks, you don't care about performance.

00:18:17.900 --> 00:18:24.380
Like, if you never wrote benchmarks for your applications, then chances are you don't actually care all that much.

00:18:24.380 --> 00:18:27.540
And you shouldn't really...

00:18:27.540 --> 00:18:28.420
That's the first step.

00:18:28.420 --> 00:18:31.280
Like, make sure you know how fast your applications run.

00:18:32.620 --> 00:18:34.980
Once you know that, you can measure it on different interpreters.

00:18:34.980 --> 00:18:41.960
But as far as expectations go, PyPy tends to run heavy computations a lot faster.

00:18:41.960 --> 00:18:47.940
Like, a lot is anything between 10 and 100 times faster, depending on the workload.

00:18:49.300 --> 00:18:50.820
For stuff that's more...

00:18:50.820 --> 00:18:54.000
And again, what is a typical Python program?

00:18:54.000 --> 00:18:56.640
Typical Python program is probably Hello World.

00:18:56.640 --> 00:18:58.500
How fast Python runs Hello World.

00:18:58.500 --> 00:19:01.440
Roughly at the same speed as CPython, you won't notice.

00:19:01.440 --> 00:19:09.060
But for a typical web application, the speed up, if you're not heavily relying on C extensions, would be around 2x.

00:19:09.940 --> 00:19:13.260
So, 2x faster for a lot of people makes a lot of difference.

00:19:13.260 --> 00:19:14.060
Absolutely.

00:19:14.060 --> 00:19:16.500
It also depends on where are you waiting.

00:19:16.500 --> 00:19:18.560
Like you said, you should profile it and figure this out.

00:19:18.560 --> 00:19:26.880
If your Python web app is slow because 80% of the time you're waiting on the database, well, it doesn't really matter how fast your Python code is.

00:19:26.880 --> 00:19:27.860
Your database is a problem.

00:19:27.860 --> 00:19:28.840
Or something like this, right?

00:19:29.640 --> 00:19:30.040
Exactly.

00:19:30.040 --> 00:19:30.120
Exactly.

00:19:30.120 --> 00:19:36.640
And like, the thing is like, so let's narrow it down to, say, web applications.

00:19:36.640 --> 00:19:40.840
Like, okay, let me first talk about other stuff and then let's go to web applications.

00:19:40.840 --> 00:19:46.280
Like, where people found Piper incredibly useful is things like high-frequency trading.

00:19:46.280 --> 00:19:52.460
Like, not the very crazy high-frequency where you have to make decisions like multiple times per millisecond.

00:19:52.460 --> 00:19:58.440
But like the sort of frequency where you want to make decisions within a few milliseconds.

00:19:58.440 --> 00:20:02.520
And then those decisions are like tens of milliseconds.

00:20:02.520 --> 00:20:10.060
Those decisions can, then you want to be able to modify your algorithms fast, which is a lot easier on Python than, say, on C++.

00:20:10.060 --> 00:20:16.040
And you're running into less problems with how to shoot yourself in the foot and segfault all your trading.

00:20:16.040 --> 00:20:24.260
So, that's when people tend to use Piper because like, in this sort of scenario, it would be like 10 times faster.

00:20:24.260 --> 00:20:28.500
So, super low latency stuff where 10 milliseconds makes a huge difference to you.

00:20:28.500 --> 00:20:29.220
Something like that.

00:20:29.220 --> 00:20:29.480
Yeah.

00:20:29.480 --> 00:20:30.080
Okay.

00:20:30.080 --> 00:20:39.820
Another example is there's, for example, a project called MyHDL, which is the hardware emulation layer.

00:20:40.600 --> 00:20:48.180
And these tend to emit sort of low-level Python code that just do computations to emulate hardware.

00:20:48.180 --> 00:20:51.720
And then again, on Piper, it's like over 10 times faster.

00:20:51.720 --> 00:20:53.500
So, those are the very good examples.

00:20:53.500 --> 00:20:54.940
The very bad examples, as you said.

00:20:54.940 --> 00:21:00.220
If your program, if your staff is waiting on the database, then you're out of luck.

00:21:00.360 --> 00:21:02.720
Like, no matter how fast your interpreter responds.

00:21:02.720 --> 00:21:05.100
But yeah.

00:21:05.100 --> 00:21:11.860
On the typical web server load, even if there is such a thing, it would be around two times speed up.

00:21:11.860 --> 00:21:13.440
Sometimes more, sometimes less.

00:21:13.440 --> 00:21:15.260
Depending on the setup, really.

00:21:15.260 --> 00:21:18.620
But as I said, you should really measure yourself.

00:21:18.620 --> 00:21:25.920
The things where Python is quite better, if you spend most of the time in C extensions,

00:21:26.760 --> 00:21:29.800
then it's either not helping or actually prevent you from doing so.

00:21:29.800 --> 00:21:36.260
And the second time where it's not that great is when the program is short running.

00:21:36.260 --> 00:21:41.340
So, because it's just-in-time compilation, it means that each time you run your program,

00:21:41.340 --> 00:21:49.020
the interpreter has to look what's going on, pick things to compile to Assembler, compile them to Assembler,

00:21:49.020 --> 00:21:50.220
and that all takes time.

00:21:50.220 --> 00:21:50.840
Right.

00:21:50.840 --> 00:21:53.520
There's a little more initial startup when that happens.

00:21:54.340 --> 00:21:57.040
Yeah, the warm-up time is usually quite bad.

00:21:57.040 --> 00:22:01.440
Well, I like to think that warm-up time of PyPy is quite bad.

00:22:01.440 --> 00:22:04.000
And then I look at Java, when it's absolutely outrageous.

00:22:04.000 --> 00:22:07.700
It's a relative statement.

00:22:07.700 --> 00:22:08.540
It's a relative term.

00:22:08.540 --> 00:22:11.120
Like, compared to CPython, PyPy time is really terrible.

00:22:11.120 --> 00:22:14.720
And compared to Luach, it's, again, the warm-up time is terrible.

00:22:14.720 --> 00:22:16.560
But compared to Java, it's not that bad.

00:22:17.080 --> 00:22:20.080
So, yeah, it really depends on your setup.

00:22:20.080 --> 00:22:23.560
And it's typically important for long-running applications.

00:22:23.560 --> 00:22:26.060
Then again, this is a typical PyPy user.

00:22:26.060 --> 00:22:32.320
When stuff like server-based applications where your programs run for a long time.

00:22:32.320 --> 00:22:33.600
Right.

00:22:33.600 --> 00:22:38.800
You start it up and it's going to serve a million requests an hour until it gets recycled or something, yeah?

00:22:38.800 --> 00:22:40.800
Something like that.

00:22:40.800 --> 00:22:44.680
I mean, these days, even JavaScript is long-running up.

00:22:44.680 --> 00:22:46.900
Like, how long do you keep your Gmail open?

00:22:46.900 --> 00:22:49.460
For usually, for longer than a few seconds.

00:22:49.460 --> 00:22:51.560
Yeah, that's for sure.

00:22:51.560 --> 00:22:55.600
So, let's talk a little bit about the internals.

00:22:55.600 --> 00:22:59.700
Could you describe just a little bit of...

00:23:00.320 --> 00:23:05.700
So, if I take a Python script and it's got some classes and some functions and they're calling each other and so on.

00:23:05.700 --> 00:23:09.900
What does it look like in terms of what's happening when that code runs?

00:23:09.900 --> 00:23:11.280
Okay.

00:23:11.280 --> 00:23:16.280
So, I'll maybe start from, like, how PyPy is built and then get back to your question directly.

00:23:16.280 --> 00:23:17.140
Yeah, great.

00:23:17.140 --> 00:23:18.880
So, PyPy is two things.

00:23:19.100 --> 00:23:24.400
And it has been very confusing because we've been calling them PyPy and PyPy.

00:23:24.400 --> 00:23:30.400
And calling two things which are related but not identical the same name is absolutely terrible.

00:23:30.400 --> 00:23:32.960
We'll probably fix that at some point.

00:23:32.960 --> 00:23:35.120
But, like, PyPy is mostly two things.

00:23:35.120 --> 00:23:38.060
So, one thing is a Python interpreter.

00:23:38.060 --> 00:23:44.060
And the other thing is a part that I would call RPython, which is a language for writing interpreters.

00:23:44.940 --> 00:23:51.080
It tends to be similar to Python in a sense that it's a restricted subset of Python.

00:23:51.080 --> 00:23:54.960
But this is largely irrelevant for the architectural question.

00:23:54.960 --> 00:24:01.880
So, you have an interpreter written in RPython that can be PyPy.

00:24:01.880 --> 00:24:03.020
We have a whole variety.

00:24:03.020 --> 00:24:05.500
There's Hippie, which is a PHP interpreter.

00:24:05.500 --> 00:24:08.080
There's a bunch of Scheme interpreters.

00:24:08.080 --> 00:24:13.440
And there's even a Prolog interpreter and a whole bunch of other interpreters written in RPython.

00:24:14.100 --> 00:24:14.980
And then...

00:24:14.980 --> 00:24:17.100
Is RPython a compiled language?

00:24:17.100 --> 00:24:18.120
Yes.

00:24:18.120 --> 00:24:25.080
And the other part is essentially the translation toolchain or a compiler for RPython.

00:24:25.080 --> 00:24:31.180
So, it contains various things like garbage collector implementation for RPython,

00:24:31.180 --> 00:24:35.820
the data types like strings, unicodes, and all the things that RPython supports.

00:24:36.660 --> 00:24:43.720
It also contains a just-in-time compiler for RPython and for interpreters written in RPython,

00:24:43.720 --> 00:24:49.720
which is one level in direction compared to what you usually do.

00:24:49.720 --> 00:24:59.900
So, the just-in-time compiler would be sort of generated from your RPython interpreter and not implemented directly,

00:24:59.900 --> 00:25:03.820
which is very, very important for us because Python, despite looking simple,

00:25:03.820 --> 00:25:06.000
is actually an incredibly complicated language.

00:25:06.000 --> 00:25:11.740
If you're trying to encode all the descriptor protocol or how actually functions and parameters are called,

00:25:11.740 --> 00:25:13.560
chances are you'll make a mistake.

00:25:13.700 --> 00:25:16.900
So, if you're implementing an interpreter and a just-in-time compiler,

00:25:16.900 --> 00:25:19.540
it's very, very hard to get all the details right.

00:25:19.540 --> 00:25:26.720
So, we implement the Python semantics once in the Python interpreter,

00:25:27.260 --> 00:25:32.180
and then it gets either directly executed or compiled to assembly.

00:25:32.180 --> 00:25:34.980
So, if you're coming back to your question,

00:25:34.980 --> 00:25:37.120
if you have a Python program,

00:25:37.120 --> 00:25:40.640
first, what it does, it will compile to bytecode,

00:25:40.640 --> 00:25:42.580
and bytecode is quite high level.

00:25:42.580 --> 00:25:45.520
There's a thing called this module,

00:25:45.520 --> 00:25:51.620
which you can just call this.this on any sort of Python object,

00:25:51.620 --> 00:25:53.060
and it will display bytecode.

00:25:54.100 --> 00:25:57.240
And the basic idea, which is what CPython does,

00:25:57.240 --> 00:26:00.400
and which is what PyPy does too at first,

00:26:00.400 --> 00:26:03.220
is to take bytecodes one by one,

00:26:03.220 --> 00:26:04.240
look what's it,

00:26:04.240 --> 00:26:06.980
and then execute it.

00:26:06.980 --> 00:26:08.060
Yeah.

00:26:08.060 --> 00:26:11.960
And is that like what's in the PyCache folders and things like that?

00:26:11.960 --> 00:26:13.260
Like those PYC files?

00:26:13.260 --> 00:26:13.440
Yeah.

00:26:13.440 --> 00:26:17.940
The PYC files are essentially a serialized version of Python bytecode.

00:26:17.940 --> 00:26:18.240
Okay.

00:26:18.700 --> 00:26:22.880
It's just a cache to store to not have to parse Python files

00:26:22.880 --> 00:26:25.100
each time you import a giant project.

00:26:25.100 --> 00:26:25.740
Right.

00:26:25.740 --> 00:26:26.120
Okay.

00:26:26.120 --> 00:26:28.980
And so then CPython takes those instructions

00:26:28.980 --> 00:26:30.740
and executes them via an interpreter,

00:26:30.740 --> 00:26:32.800
but that's not what happens on PyPy, right?

00:26:32.800 --> 00:26:35.280
That's what happens on PyPy initially.

00:26:35.280 --> 00:26:39.560
So, all your code will be like executed like CPython,

00:26:39.560 --> 00:26:43.380
except if you hit a magic number of like function calls

00:26:43.380 --> 00:26:44.400
or loop iterations,

00:26:44.400 --> 00:26:48.160
I think it's 1037 for loop iterations,

00:26:48.160 --> 00:26:53.000
then you compile this particular loop,

00:26:53.000 --> 00:26:55.400
in fact, this particular execution of a loop,

00:26:55.400 --> 00:26:56.880
into assembler code.

00:26:56.880 --> 00:27:01.600
Then if you have a mix of interpreter code

00:27:01.600 --> 00:27:03.100
and assembler code,

00:27:03.100 --> 00:27:04.620
and if you,

00:27:04.620 --> 00:27:08.560
the assembler code is a linear sequence of instructions

00:27:08.560 --> 00:27:10.980
that contains so-called guards.

00:27:11.160 --> 00:27:13.300
So, the guards will be anything from

00:27:13.300 --> 00:27:16.180
if something in the Python source

00:27:16.180 --> 00:27:19.880
to is the type of this thing stays the same.

00:27:19.880 --> 00:27:23.420
Then if you happen to fail those guards,

00:27:23.420 --> 00:27:23.860
then you,

00:27:23.860 --> 00:27:25.760
okay, I failed this guard,

00:27:25.760 --> 00:27:29.760
I'm going to go and start compiling assembler again.

00:27:29.760 --> 00:27:30.920
I mean,

00:27:30.920 --> 00:27:32.580
at first you jump back to the interpreter,

00:27:32.580 --> 00:27:33.100
but if you,

00:27:33.100 --> 00:27:33.360
again,

00:27:33.360 --> 00:27:34.100
hit a magic number,

00:27:34.100 --> 00:27:36.740
you compile the assembler again from this guard.

00:27:36.740 --> 00:27:39.400
And then you end up with like a tree of execution

00:27:39.400 --> 00:27:40.260
that resembles

00:27:40.260 --> 00:27:43.280
both your Python code

00:27:43.280 --> 00:27:44.540
and the type structure

00:27:44.540 --> 00:27:46.340
that you're passing in a few other things

00:27:46.340 --> 00:27:48.520
that are automatically determined.

00:27:48.520 --> 00:27:49.460
So,

00:27:49.460 --> 00:27:50.740
at the end of the day,

00:27:50.740 --> 00:27:52.340
you end up with a Python function

00:27:52.340 --> 00:27:54.280
or like multiple Python functions

00:27:54.280 --> 00:27:55.960
that got compiled to assembler

00:27:55.960 --> 00:27:57.580
if you warm stuff for long enough.

00:27:57.580 --> 00:27:58.180
Okay.

00:27:58.180 --> 00:27:58.760
That's,

00:27:58.760 --> 00:27:59.960
that is super interesting.

00:27:59.960 --> 00:28:02.120
I didn't expect that it would have

00:28:02.120 --> 00:28:05.420
this initial non-assembled assembler version.

00:28:05.420 --> 00:28:05.860
That's,

00:28:05.860 --> 00:28:06.380
that's very cool.

00:28:06.380 --> 00:28:07.120
What was,

00:28:07.120 --> 00:28:08.480
do you know what the thinking around that was?

00:28:08.480 --> 00:28:09.740
Is it just better performance?

00:28:09.740 --> 00:28:10.840
So,

00:28:10.840 --> 00:28:12.400
there's a variety of things.

00:28:12.400 --> 00:28:12.740
Like,

00:28:12.740 --> 00:28:14.760
one thing is that if you try to,

00:28:14.760 --> 00:28:17.080
to compile everything like upfront,

00:28:17.080 --> 00:28:19.920
it would take you forever.

00:28:19.920 --> 00:28:22.280
But also you are,

00:28:22.280 --> 00:28:24.860
you can do some optimizations.

00:28:24.860 --> 00:28:25.120
Like,

00:28:25.120 --> 00:28:27.000
a lot of optimizations done in PyPy

00:28:27.000 --> 00:28:28.220
are sort of optimistic.

00:28:28.220 --> 00:28:29.520
Like,

00:28:29.860 --> 00:28:32.280
we're going to assume special things like

00:28:32.280 --> 00:28:34.360
sys.setTrace

00:28:34.360 --> 00:28:35.660
or sys.getFrame

00:28:35.660 --> 00:28:37.040
just does not happen.

00:28:37.040 --> 00:28:39.120
And until it doesn't happen,

00:28:39.120 --> 00:28:41.180
things can run nicely and smoothly.

00:28:41.180 --> 00:28:43.660
But you're trying to figure out

00:28:43.660 --> 00:28:44.760
on the fly

00:28:44.760 --> 00:28:45.720
what's going on.

00:28:45.720 --> 00:28:47.000
And then you compile pieces

00:28:47.000 --> 00:28:47.940
that you know about.

00:28:47.940 --> 00:28:48.260
So,

00:28:48.260 --> 00:28:50.560
at the moment when you are compiling

00:28:50.560 --> 00:28:51.540
a Python loop

00:28:51.540 --> 00:28:52.160
or a function

00:28:52.160 --> 00:28:53.100
or something like that,

00:28:53.100 --> 00:28:55.060
you tend to know more

00:28:55.060 --> 00:28:56.080
about the,

00:28:56.080 --> 00:28:57.220
the state of execution

00:28:57.220 --> 00:28:57.520
than,

00:28:57.520 --> 00:28:58.740
that is just in the source.

00:28:58.740 --> 00:28:59.020
Like,

00:28:59.020 --> 00:28:59.800
you tend to know

00:28:59.800 --> 00:29:00.840
the types,

00:29:00.840 --> 00:29:02.320
the precise shape of objects.

00:29:02.320 --> 00:29:02.660
Like,

00:29:02.660 --> 00:29:04.060
is this an object

00:29:04.060 --> 00:29:05.840
that's class X

00:29:05.840 --> 00:29:07.940
and has two attributes A and B?

00:29:07.940 --> 00:29:09.500
Or is it an object of class X

00:29:09.500 --> 00:29:11.480
that has three attributes A, B, and C?

00:29:11.480 --> 00:29:13.600
And those decisions

00:29:13.600 --> 00:29:15.440
can lead to better performance,

00:29:15.440 --> 00:29:15.920
essentially.

00:29:15.920 --> 00:29:16.800
So,

00:29:16.800 --> 00:29:17.920
on your website,

00:29:17.920 --> 00:29:18.700
you say that this,

00:29:18.700 --> 00:29:20.840
that PyPy may be better

00:29:20.840 --> 00:29:22.460
in terms of memory usage as well.

00:29:22.460 --> 00:29:23.620
How does that work?

00:29:23.620 --> 00:29:25.620
It's a trade-off, right?

00:29:25.620 --> 00:29:25.980
So,

00:29:25.980 --> 00:29:26.860
first of all,

00:29:26.860 --> 00:29:28.000
PyPy does

00:29:28.000 --> 00:29:29.620
consume memory

00:29:29.740 --> 00:29:30.560
memory for

00:29:30.560 --> 00:29:32.060
the compound assembler

00:29:32.060 --> 00:29:32.780
and the

00:29:32.780 --> 00:29:34.560
associated bookkeeping data.

00:29:34.560 --> 00:29:37.120
That depends on how much code

00:29:37.120 --> 00:29:38.020
you actually run.

00:29:38.020 --> 00:29:39.020
But,

00:29:39.020 --> 00:29:40.380
the object representation

00:29:40.380 --> 00:29:40.940
of Python,

00:29:40.940 --> 00:29:42.260
of Python objects

00:29:42.260 --> 00:29:43.240
is more compact

00:29:43.240 --> 00:29:43.800
than PyPy.

00:29:43.800 --> 00:29:44.160
So,

00:29:44.160 --> 00:29:46.400
the actual amount

00:29:46.400 --> 00:29:47.260
of memory consumed

00:29:47.260 --> 00:29:48.140
by your heap

00:29:48.140 --> 00:29:50.240
tends to be smaller.

00:29:50.240 --> 00:29:50.620
Like,

00:29:50.620 --> 00:29:52.040
all PyPy objects

00:29:52.040 --> 00:29:53.780
are as memory compact

00:29:53.780 --> 00:29:54.940
as

00:29:54.940 --> 00:29:56.380
see Python objects

00:29:56.380 --> 00:29:56.940
using

00:29:56.940 --> 00:29:58.100
slots.

00:29:58.100 --> 00:29:58.620
Right,

00:29:58.620 --> 00:29:58.940
okay.

00:29:58.940 --> 00:29:59.440
So,

00:29:59.440 --> 00:30:00.440
it's the same optimization

00:30:00.440 --> 00:30:01.620
except it's transparent.

00:30:01.620 --> 00:30:04.380
Then,

00:30:04.380 --> 00:30:04.920
the,

00:30:04.920 --> 00:30:05.640
like,

00:30:05.640 --> 00:30:07.080
list of only integers

00:30:07.080 --> 00:30:08.520
would not allocate

00:30:08.520 --> 00:30:10.400
the entire objects.

00:30:10.400 --> 00:30:11.480
It would allocate

00:30:11.480 --> 00:30:12.720
only small integers.

00:30:12.720 --> 00:30:13.220
Then,

00:30:13.220 --> 00:30:13.760
the,

00:30:13.760 --> 00:30:15.520
the objects

00:30:15.520 --> 00:30:16.600
are smaller themselves

00:30:16.600 --> 00:30:17.280
because we use

00:30:17.280 --> 00:30:18.480
a different garbage collection

00:30:18.480 --> 00:30:18.960
strategy.

00:30:18.960 --> 00:30:20.040
It's not ref counting.

00:30:20.320 --> 00:30:21.720
it's a garbage collector.

00:30:21.720 --> 00:30:22.320
Right,

00:30:22.320 --> 00:30:22.580
so,

00:30:22.580 --> 00:30:23.200
let's talk about

00:30:23.200 --> 00:30:23.880
the garbage collector

00:30:23.880 --> 00:30:24.960
just for a moment.

00:30:24.960 --> 00:30:26.320
Is it a mark and sweep

00:30:26.320 --> 00:30:27.240
garbage collector?

00:30:27.240 --> 00:30:42.020
This episode

00:30:42.020 --> 00:30:42.700
is brought to you

00:30:42.700 --> 00:30:43.480
by CodeShip.

00:30:43.480 --> 00:30:45.320
CodeShip has launched

00:30:45.320 --> 00:30:46.060
organizations,

00:30:46.060 --> 00:30:47.120
create teams,

00:30:47.120 --> 00:30:47.860
set permissions

00:30:47.860 --> 00:30:49.300
for specific team members,

00:30:49.400 --> 00:30:50.480
and improve collaboration

00:30:50.480 --> 00:30:51.440
in your continuous

00:30:51.440 --> 00:30:52.320
delivery workflow.

00:30:52.320 --> 00:30:54.260
Maintain centralized control

00:30:54.260 --> 00:30:55.420
over your organization's

00:30:55.420 --> 00:30:56.440
projects and teams

00:30:56.440 --> 00:30:57.080
with CodeShip's

00:30:57.080 --> 00:30:58.220
new organizations plan.

00:30:58.220 --> 00:30:59.060
And,

00:30:59.060 --> 00:31:00.000
as Talk Python listeners,

00:31:00.000 --> 00:31:01.520
you can save 20% off

00:31:01.520 --> 00:31:02.560
any premium plan

00:31:02.560 --> 00:31:03.760
for the next three months.

00:31:03.760 --> 00:31:05.060
Just use the code

00:31:05.060 --> 00:31:05.940
TALKPYTHON,

00:31:05.940 --> 00:31:06.580
all caps,

00:31:06.580 --> 00:31:07.280
no spaces.

00:31:07.280 --> 00:31:08.460
Check them out

00:31:08.460 --> 00:31:09.560
at CodeShip.com

00:31:09.560 --> 00:31:10.400
and tell them thanks

00:31:10.400 --> 00:31:11.300
for supporting the show

00:31:11.300 --> 00:31:11.760
on Twitter

00:31:11.760 --> 00:31:12.500
where they're at,

00:31:12.500 --> 00:31:13.000
CodeShip.

00:31:13.000 --> 00:31:18.900
It's in,

00:31:18.900 --> 00:31:19.960
very convoluted

00:31:19.960 --> 00:31:21.260
variant of mark and sweep.

00:31:21.260 --> 00:31:21.700
Yeah.

00:31:21.700 --> 00:31:24.140
It has two generations

00:31:24.140 --> 00:31:24.680
of objects,

00:31:24.680 --> 00:31:25.460
young objects

00:31:25.460 --> 00:31:26.320
and old objects,

00:31:26.320 --> 00:31:27.080
and old objects

00:31:27.080 --> 00:31:28.220
are mark and sweep,

00:31:28.220 --> 00:31:29.420
and young objects

00:31:29.420 --> 00:31:31.180
are pointer bump

00:31:31.180 --> 00:31:31.720
allocations.

00:31:31.720 --> 00:31:32.020
So,

00:31:32.020 --> 00:31:35.380
the net effect

00:31:35.380 --> 00:31:35.960
is that

00:31:35.960 --> 00:31:36.780
if you are having

00:31:36.780 --> 00:31:38.280
a lot of small objects

00:31:38.280 --> 00:31:39.100
that get allocated

00:31:39.100 --> 00:31:39.740
all the time

00:31:39.740 --> 00:31:40.240
and forgotten

00:31:40.240 --> 00:31:40.940
really quickly,

00:31:40.940 --> 00:31:42.760
allocation takes,

00:31:42.760 --> 00:31:43.100
like,

00:31:43.100 --> 00:31:43.800
on average,

00:31:43.900 --> 00:31:44.900
around one CPU

00:31:44.900 --> 00:31:45.520
instruction.

00:31:45.520 --> 00:31:47.660
It's,

00:31:47.660 --> 00:31:48.520
on average,

00:31:48.520 --> 00:31:48.860
one,

00:31:48.860 --> 00:31:49.820
because it takes,

00:31:49.820 --> 00:31:50.000
like,

00:31:50.000 --> 00:31:50.720
slightly more,

00:31:50.720 --> 00:31:51.380
but then you have

00:31:51.380 --> 00:31:51.940
pipelining,

00:31:51.940 --> 00:31:52.580
so sometimes

00:31:52.580 --> 00:31:53.740
it takes slightly less.

00:31:53.740 --> 00:31:54.440
Okay,

00:31:54.440 --> 00:31:55.800
do you guys do compaction

00:31:55.800 --> 00:31:56.680
and things like that

00:31:56.680 --> 00:31:56.980
as well?

00:31:57.700 --> 00:31:58.180
No,

00:31:58.180 --> 00:31:59.300
but we do

00:31:59.300 --> 00:32:01.500
copy old objects

00:32:01.500 --> 00:32:03.200
from the young generation

00:32:03.200 --> 00:32:04.200
to the old generation.

00:32:04.200 --> 00:32:05.460
Then we don't compact

00:32:05.460 --> 00:32:06.360
the old generation,

00:32:06.360 --> 00:32:08.460
but usually more compact

00:32:08.460 --> 00:32:10.100
than your normal setup

00:32:10.100 --> 00:32:10.660
where you have

00:32:10.660 --> 00:32:11.440
lots of objects

00:32:11.440 --> 00:32:12.500
that are scattered

00:32:12.500 --> 00:32:13.320
all over the place

00:32:13.320 --> 00:32:14.100
because you only

00:32:14.100 --> 00:32:15.620
have to deal with objects

00:32:15.620 --> 00:32:17.640
that survive minor collection.

00:32:17.640 --> 00:32:18.320
Right,

00:32:18.320 --> 00:32:19.480
and that's the majority

00:32:19.480 --> 00:32:19.980
of objects

00:32:19.980 --> 00:32:21.080
that we interact with

00:32:21.080 --> 00:32:22.280
all die right away.

00:32:22.280 --> 00:32:22.560
Vast majority.

00:32:22.560 --> 00:32:23.140
Yeah,

00:32:23.140 --> 00:32:23.960
absolutely.

00:32:23.960 --> 00:32:24.720
For the most part.

00:32:25.520 --> 00:32:25.800
Okay,

00:32:25.800 --> 00:32:26.220
yeah,

00:32:26.220 --> 00:32:27.080
that's very cool.

00:32:27.080 --> 00:32:29.220
One of the things

00:32:29.220 --> 00:32:30.860
that is not super easy

00:32:30.860 --> 00:32:31.880
in regular Python

00:32:31.880 --> 00:32:33.800
is parallelism

00:32:33.800 --> 00:32:34.900
and asynchronous programming

00:32:34.900 --> 00:32:35.580
and so on.

00:32:35.580 --> 00:32:37.460
And you guys have

00:32:37.460 --> 00:32:38.020
this thing called

00:32:38.020 --> 00:32:39.120
stackless mode.

00:32:39.120 --> 00:32:40.220
What's the story

00:32:40.220 --> 00:32:40.660
with that?

00:32:40.660 --> 00:32:43.260
It's the same thing

00:32:43.260 --> 00:32:44.200
as stackless Python.

00:32:44.200 --> 00:32:45.580
It gives you

00:32:45.580 --> 00:32:46.100
an ability

00:32:46.100 --> 00:32:47.240
to have coroutines

00:32:47.240 --> 00:32:48.900
that can be swapped out

00:32:48.900 --> 00:32:50.480
without an explicit

00:32:50.480 --> 00:32:51.320
yield keyword.

00:32:51.320 --> 00:32:52.820
So it's not like

00:32:52.820 --> 00:32:54.240
Python 3 coroutines.

00:32:54.600 --> 00:32:56.000
it's like

00:32:56.000 --> 00:32:57.640
normal coroutines

00:32:57.640 --> 00:32:58.520
when you can swap them

00:32:58.520 --> 00:32:59.300
randomly.

00:32:59.300 --> 00:33:00.340
For example,

00:33:00.340 --> 00:33:01.440
GEvent uses

00:33:01.440 --> 00:33:03.500
I think GEvent

00:33:03.500 --> 00:33:04.580
uses stackless mode

00:33:04.580 --> 00:33:05.640
for swapping

00:33:05.640 --> 00:33:06.460
the coroutines.

00:33:06.460 --> 00:33:07.440
Okay,

00:33:07.440 --> 00:33:09.460
so you said

00:33:09.460 --> 00:33:09.940
that you can get

00:33:09.940 --> 00:33:10.680
better concurrency.

00:33:10.680 --> 00:33:11.860
Can you kind of describe

00:33:11.860 --> 00:33:13.720
speak to that any

00:33:13.720 --> 00:33:14.920
or what are your thoughts there?

00:33:14.920 --> 00:33:16.020
I personally

00:33:16.020 --> 00:33:16.880
don't use stackless

00:33:16.880 --> 00:33:17.420
all that much

00:33:17.420 --> 00:33:19.420
but the net effect

00:33:19.420 --> 00:33:20.640
is that you

00:33:20.640 --> 00:33:22.580
you can write code

00:33:22.580 --> 00:33:23.560
like with

00:33:23.560 --> 00:33:25.840
Python 3 coroutines

00:33:25.840 --> 00:33:27.140
without the yield keyword.

00:33:27.140 --> 00:33:28.100
So you just call function

00:33:28.100 --> 00:33:28.880
then you can swap

00:33:28.880 --> 00:33:29.440
the functions

00:33:29.440 --> 00:33:31.100
for other things.

00:33:31.100 --> 00:33:33.200
It's a bit like

00:33:33.200 --> 00:33:33.840
implicit

00:33:33.840 --> 00:33:34.440
twisted

00:33:34.440 --> 00:33:35.000
where

00:33:35.000 --> 00:33:36.400
you don't get

00:33:36.400 --> 00:33:37.220
better concurrency

00:33:37.220 --> 00:33:37.760
than twisted

00:33:37.760 --> 00:33:38.860
but you're not

00:33:38.860 --> 00:33:39.780
you don't need

00:33:39.780 --> 00:33:41.020
to write your programs

00:33:41.020 --> 00:33:41.700
in the style

00:33:41.700 --> 00:33:42.980
that twisted requires.

00:33:43.540 --> 00:33:45.280
I was going to say

00:33:45.280 --> 00:33:46.100
it's just a little more

00:33:46.100 --> 00:33:46.720
automatic

00:33:46.720 --> 00:33:47.360
and you don't have

00:33:47.360 --> 00:33:48.160
to be so explicit

00:33:48.160 --> 00:33:48.760
that you're doing

00:33:48.760 --> 00:33:49.200
threading.

00:33:49.200 --> 00:33:50.380
Yeah,

00:33:50.380 --> 00:33:51.240
exactly.

00:33:51.240 --> 00:33:52.360
Like the normal

00:33:52.360 --> 00:33:54.420
normal threads

00:33:54.420 --> 00:33:55.460
especially in Python

00:33:55.460 --> 00:33:56.040
where you have the

00:33:56.040 --> 00:33:57.140
global interpreter log

00:33:57.140 --> 00:33:58.700
they don't scale

00:33:58.700 --> 00:33:59.340
all that well

00:33:59.340 --> 00:34:00.240
and like the solution

00:34:00.240 --> 00:34:01.280
is usually twisted

00:34:01.280 --> 00:34:02.320
but twisted requires

00:34:02.320 --> 00:34:02.940
you to have

00:34:02.940 --> 00:34:04.180
all the libraries

00:34:04.180 --> 00:34:04.960
and everything

00:34:04.960 --> 00:34:06.940
written twisted aware

00:34:06.940 --> 00:34:08.080
which stackless

00:34:08.080 --> 00:34:09.020
does not generally

00:34:09.020 --> 00:34:09.440
requires.

00:34:09.440 --> 00:34:11.920
I don't have

00:34:11.920 --> 00:34:13.240
any particular feelings

00:34:13.240 --> 00:34:14.740
towards all of that

00:34:14.740 --> 00:34:15.440
to be honest.

00:34:15.440 --> 00:34:16.180
Sure.

00:34:16.180 --> 00:34:17.620
Does it also support

00:34:17.620 --> 00:34:18.980
Twisted running on PyPy?

00:34:18.980 --> 00:34:19.440
Do you know?

00:34:19.440 --> 00:34:19.920
Yeah,

00:34:19.920 --> 00:34:20.460
obviously.

00:34:20.460 --> 00:34:21.800
Twisted is a Python program.

00:34:21.800 --> 00:34:22.840
We had

00:34:22.840 --> 00:34:25.040
from the very early days

00:34:25.040 --> 00:34:25.380
we had

00:34:25.380 --> 00:34:27.340
good contact

00:34:27.340 --> 00:34:28.300
with twisted people

00:34:28.300 --> 00:34:30.160
and people who use twisted

00:34:30.160 --> 00:34:30.900
tend to be from

00:34:30.900 --> 00:34:31.680
the same category

00:34:31.680 --> 00:34:32.740
as people who use PyPy.

00:34:32.740 --> 00:34:33.500
People who have

00:34:33.500 --> 00:34:35.700
large running code bases

00:34:35.700 --> 00:34:36.600
that are boring

00:34:36.600 --> 00:34:38.040
but have problems

00:34:38.040 --> 00:34:38.940
because they're

00:34:38.940 --> 00:34:39.700
actually huge.

00:34:39.700 --> 00:34:41.500
I mean not huge

00:34:41.500 --> 00:34:42.360
in terms of code base

00:34:42.360 --> 00:34:43.120
but huge in terms

00:34:43.120 --> 00:34:43.800
of number

00:34:43.800 --> 00:34:44.460
of requests

00:34:44.460 --> 00:34:45.080
they serve

00:34:45.080 --> 00:34:46.180
and stuff like this.

00:34:46.180 --> 00:34:47.880
So they tend

00:34:47.880 --> 00:34:48.540
to be

00:34:48.540 --> 00:34:50.440
very,

00:34:50.440 --> 00:34:51.140
very focused

00:34:51.140 --> 00:34:52.680
on how to make

00:34:52.680 --> 00:34:53.160
the stuff

00:34:53.160 --> 00:34:54.920
work both reliably

00:34:54.920 --> 00:34:56.320
and fast.

00:34:56.320 --> 00:34:57.320
So for example

00:34:57.320 --> 00:34:59.200
like a typical answer

00:34:59.200 --> 00:35:01.120
to Python performance

00:35:01.120 --> 00:35:01.460
problems

00:35:01.460 --> 00:35:02.300
oh just rewrite

00:35:02.300 --> 00:35:03.020
pieces in C.

00:35:03.020 --> 00:35:04.620
Well that's

00:35:04.620 --> 00:35:05.220
that's all

00:35:05.220 --> 00:35:06.860
cool if you have

00:35:06.860 --> 00:35:07.680
like few

00:35:07.680 --> 00:35:08.580
small loops

00:35:08.580 --> 00:35:09.400
that you can

00:35:09.400 --> 00:35:10.380
rewrite in C

00:35:10.380 --> 00:35:11.340
and have everything

00:35:11.340 --> 00:35:11.680
fast.

00:35:11.680 --> 00:35:12.160
But like

00:35:12.160 --> 00:35:13.200
most web servers

00:35:13.200 --> 00:35:14.060
are not like this.

00:35:14.060 --> 00:35:15.060
If you look at the profile

00:35:15.060 --> 00:35:15.800
it's just flat.

00:35:15.800 --> 00:35:17.660
It's tons of dictionaries

00:35:17.660 --> 00:35:18.920
and things that are

00:35:18.920 --> 00:35:19.800
not easy to write

00:35:19.800 --> 00:35:20.200
in C.

00:35:20.200 --> 00:35:21.640
And C introduces

00:35:21.640 --> 00:35:23.440
security problems

00:35:23.440 --> 00:35:24.680
like suddenly

00:35:24.680 --> 00:35:25.560
dealing in C

00:35:25.560 --> 00:35:26.640
with untrusted data

00:35:26.640 --> 00:35:27.760
is not that much fun.

00:35:28.120 --> 00:35:28.200
No.

00:35:28.200 --> 00:35:29.200
So it's definitely

00:35:29.200 --> 00:35:29.500
not.

00:35:29.500 --> 00:35:30.120
Or even

00:35:30.120 --> 00:35:30.800
reliability

00:35:30.800 --> 00:35:31.260
right?

00:35:31.260 --> 00:35:32.540
Yeah.

00:35:32.540 --> 00:35:33.180
So all those

00:35:33.180 --> 00:35:33.540
problems.

00:35:33.540 --> 00:35:34.840
So Twisted people

00:35:34.840 --> 00:35:35.760
tend to write

00:35:35.760 --> 00:35:36.800
like Python

00:35:36.800 --> 00:35:37.640
better than C

00:35:37.640 --> 00:35:39.880
and they've

00:35:39.880 --> 00:35:40.660
been very supportive

00:35:40.660 --> 00:35:41.260
of PyPy

00:35:41.260 --> 00:35:42.120
from the very

00:35:42.120 --> 00:35:43.500
first day.

00:35:43.500 --> 00:35:44.460
So they

00:35:44.460 --> 00:35:45.180
generally

00:35:45.180 --> 00:35:46.980
PyPy is running

00:35:46.980 --> 00:35:47.360
Twisted

00:35:47.360 --> 00:35:47.960
and it's running

00:35:47.960 --> 00:35:48.980
Twisted quite fast

00:35:48.980 --> 00:35:50.340
for quite a few

00:35:50.340 --> 00:35:50.880
years right now.

00:35:50.880 --> 00:35:51.360
Yeah that's

00:35:51.360 --> 00:35:51.620
excellent.

00:35:51.620 --> 00:35:52.160
It seems like

00:35:52.160 --> 00:35:52.600
if you have a

00:35:52.600 --> 00:35:53.200
problem that

00:35:53.200 --> 00:35:54.360
Twisted would solve

00:35:54.360 --> 00:35:55.360
you also probably

00:35:55.360 --> 00:35:55.760
want to look

00:35:55.760 --> 00:35:56.340
into PyPy.

00:35:57.460 --> 00:35:57.980
Exactly.

00:35:57.980 --> 00:35:58.660
This is like

00:35:58.660 --> 00:35:59.780
the same category

00:35:59.780 --> 00:36:00.700
of problems

00:36:00.700 --> 00:36:02.180
that you're

00:36:02.180 --> 00:36:02.860
trying to solve.

00:36:02.860 --> 00:36:04.160
Another interesting

00:36:04.160 --> 00:36:05.060
stuff about

00:36:05.060 --> 00:36:05.700
concurrency

00:36:05.700 --> 00:36:06.680
which I guess

00:36:06.680 --> 00:36:07.340
I'm slightly

00:36:07.340 --> 00:36:07.860
more excited

00:36:07.860 --> 00:36:08.740
about is the

00:36:08.740 --> 00:36:09.780
software transactional

00:36:09.780 --> 00:36:10.420
memory that

00:36:10.420 --> 00:36:11.240
Armin Rigo is

00:36:11.240 --> 00:36:12.000
working on right

00:36:12.000 --> 00:36:12.300
now.

00:36:12.300 --> 00:36:13.200
So this is

00:36:13.200 --> 00:36:13.900
one of our

00:36:13.900 --> 00:36:14.620
fundraisers

00:36:14.620 --> 00:36:15.120
just like

00:36:15.120 --> 00:36:15.520
NumPy.

00:36:15.520 --> 00:36:16.820
Yeah so this

00:36:16.820 --> 00:36:17.260
is one of your

00:36:17.260 --> 00:36:18.000
three sort of

00:36:18.000 --> 00:36:18.760
major going

00:36:18.760 --> 00:36:20.080
forward projects

00:36:20.080 --> 00:36:20.660
if you will.

00:36:20.660 --> 00:36:22.340
Yeah those are

00:36:22.340 --> 00:36:22.980
the three

00:36:22.980 --> 00:36:24.100
publicly funded

00:36:24.100 --> 00:36:24.620
projects.

00:36:24.620 --> 00:36:25.120
Right and if

00:36:25.120 --> 00:36:25.440
you go to

00:36:25.440 --> 00:36:26.280
PyPy.org

00:36:26.280 --> 00:36:27.300
right there

00:36:27.300 --> 00:36:27.520
on the

00:36:27.520 --> 00:36:27.900
right it

00:36:27.900 --> 00:36:28.440
says donate

00:36:28.440 --> 00:36:28.840
towards

00:36:28.840 --> 00:36:29.440
STM

00:36:29.440 --> 00:36:30.360
and you

00:36:30.360 --> 00:36:30.800
guys have

00:36:30.800 --> 00:36:31.380
quite a

00:36:31.380 --> 00:36:31.800
bit of

00:36:31.800 --> 00:36:33.360
money towards

00:36:33.360 --> 00:36:34.060
this project

00:36:34.060 --> 00:36:34.640
and so

00:36:34.640 --> 00:36:36.080
it's excellent.

00:36:36.080 --> 00:36:36.880
What is

00:36:36.880 --> 00:36:37.540
software transactional

00:36:37.540 --> 00:36:38.080
memory for the

00:36:38.080 --> 00:36:38.320
listeners?

00:36:38.320 --> 00:36:39.940
There are two

00:36:39.940 --> 00:36:40.340
ideas.

00:36:40.340 --> 00:36:41.320
First problem

00:36:41.320 --> 00:36:43.660
they're related

00:36:43.660 --> 00:36:44.120
but not

00:36:44.120 --> 00:36:44.580
identical.

00:36:44.580 --> 00:36:45.300
First problem

00:36:45.300 --> 00:36:45.900
is that Python

00:36:45.900 --> 00:36:46.680
has the

00:36:46.680 --> 00:36:47.740
global

00:36:47.740 --> 00:36:48.240
interpreter

00:36:48.240 --> 00:36:48.740
log.

00:36:48.740 --> 00:36:49.920
So global

00:36:49.920 --> 00:36:50.300
interpreter

00:36:50.300 --> 00:36:51.220
log essentially

00:36:51.220 --> 00:36:51.840
prevents you

00:36:51.840 --> 00:36:52.500
from running

00:36:52.500 --> 00:36:54.340
multiple threads

00:36:54.340 --> 00:36:54.920
on multiple

00:36:54.920 --> 00:36:55.960
cores on one

00:36:55.960 --> 00:36:56.360
machine.

00:36:57.140 --> 00:36:57.880
So if you

00:36:57.880 --> 00:36:58.460
write Python

00:36:58.460 --> 00:36:59.080
program and

00:36:59.080 --> 00:36:59.480
you write

00:36:59.480 --> 00:37:00.000
it multi

00:37:00.000 --> 00:37:00.760
threaded it

00:37:00.760 --> 00:37:01.420
will only

00:37:01.420 --> 00:37:02.060
ever consume

00:37:02.060 --> 00:37:02.600
one CPU

00:37:02.600 --> 00:37:04.520
which is

00:37:04.520 --> 00:37:05.160
not great

00:37:05.160 --> 00:37:05.540
if you want

00:37:05.540 --> 00:37:05.960
to compute

00:37:05.960 --> 00:37:06.380
anything.

00:37:06.380 --> 00:37:07.280
So that's

00:37:07.280 --> 00:37:08.100
one problem

00:37:08.100 --> 00:37:08.700
that STM

00:37:08.700 --> 00:37:09.280
is solving

00:37:09.280 --> 00:37:09.820
and I'm

00:37:09.820 --> 00:37:09.960
going to

00:37:09.960 --> 00:37:10.540
explain just

00:37:10.540 --> 00:37:11.280
now how

00:37:11.280 --> 00:37:11.720
it's solving

00:37:11.720 --> 00:37:11.980
it.

00:37:11.980 --> 00:37:12.980
But another

00:37:12.980 --> 00:37:13.760
problem is

00:37:13.760 --> 00:37:15.180
that it's

00:37:15.180 --> 00:37:15.720
trying to

00:37:15.720 --> 00:37:16.520
provide a much

00:37:16.520 --> 00:37:17.460
better model

00:37:17.460 --> 00:37:18.140
for writing

00:37:18.140 --> 00:37:18.940
programs with

00:37:18.940 --> 00:37:19.340
threads.

00:37:19.340 --> 00:37:20.480
If you start

00:37:20.480 --> 00:37:21.240
using threads

00:37:21.240 --> 00:37:21.840
the Python

00:37:21.840 --> 00:37:22.360
mutability

00:37:22.360 --> 00:37:24.720
model makes

00:37:24.720 --> 00:37:25.420
it so hard

00:37:25.420 --> 00:37:25.780
to write

00:37:25.780 --> 00:37:26.700
correct programs.

00:37:26.980 --> 00:37:27.780
you're essentially

00:37:27.780 --> 00:37:28.480
running into

00:37:28.480 --> 00:37:29.180
problems like

00:37:29.180 --> 00:37:29.640
suddenly

00:37:29.640 --> 00:37:30.620
okay but I

00:37:30.620 --> 00:37:31.220
have to think

00:37:31.220 --> 00:37:31.940
who modified

00:37:31.940 --> 00:37:32.860
what in what

00:37:32.860 --> 00:37:33.760
order and

00:37:33.760 --> 00:37:34.760
consider all

00:37:34.760 --> 00:37:35.360
the possible

00:37:35.360 --> 00:37:36.840
combinations.

00:37:36.840 --> 00:37:37.940
Make sure that

00:37:37.940 --> 00:37:38.480
every bit of

00:37:38.480 --> 00:37:38.980
code that's

00:37:38.980 --> 00:37:39.340
going to work

00:37:39.340 --> 00:37:39.800
with this

00:37:39.800 --> 00:37:41.400
segment of

00:37:41.400 --> 00:37:41.960
data is

00:37:41.960 --> 00:37:42.740
taking the

00:37:42.740 --> 00:37:43.300
right locks

00:37:43.300 --> 00:37:43.840
and all that

00:37:43.840 --> 00:37:44.260
kind of stuff

00:37:44.260 --> 00:37:44.660
that gets

00:37:44.660 --> 00:37:45.380
really tricky

00:37:45.380 --> 00:37:45.820
to ensure

00:37:45.820 --> 00:37:46.100
right?

00:37:47.100 --> 00:37:47.640
yeah so

00:37:47.640 --> 00:37:48.920
essentially

00:37:48.920 --> 00:37:49.760
the

00:37:49.760 --> 00:37:50.960
model is

00:37:50.960 --> 00:37:51.380
where

00:37:51.380 --> 00:37:52.760
if you

00:37:52.760 --> 00:37:52.940
write

00:37:52.940 --> 00:37:53.520
program in

00:37:53.520 --> 00:37:53.780
C

00:37:53.780 --> 00:37:54.620
you write

00:37:54.620 --> 00:37:55.080
the program

00:37:55.080 --> 00:37:55.400
it's all

00:37:55.400 --> 00:37:55.880
fine then

00:37:55.880 --> 00:37:56.740
you switch

00:37:56.740 --> 00:37:57.560
to threading

00:37:57.560 --> 00:37:59.240
and you get

00:37:59.240 --> 00:37:59.960
performance

00:37:59.960 --> 00:38:00.700
immediately

00:38:00.700 --> 00:38:01.760
like

00:38:01.760 --> 00:38:03.200
your program

00:38:03.200 --> 00:38:04.060
if you write

00:38:04.060 --> 00:38:04.940
threads correctly

00:38:04.940 --> 00:38:05.700
it will run

00:38:05.700 --> 00:38:07.040
four times faster

00:38:07.040 --> 00:38:07.720
on four cores

00:38:07.720 --> 00:38:08.140
or whatever

00:38:08.140 --> 00:38:09.320
but

00:38:09.320 --> 00:38:10.420
it will

00:38:10.420 --> 00:38:10.700
likely

00:38:10.700 --> 00:38:11.220
crash

00:38:11.220 --> 00:38:12.520
and it will

00:38:12.520 --> 00:38:13.460
likely crash

00:38:13.460 --> 00:38:13.960
for the next

00:38:13.960 --> 00:38:14.320
couple of

00:38:14.320 --> 00:38:14.540
weeks

00:38:14.540 --> 00:38:14.920
months

00:38:14.920 --> 00:38:15.280
years

00:38:15.280 --> 00:38:15.640
whatever

00:38:15.640 --> 00:38:16.700
you throw

00:38:16.700 --> 00:38:17.280
into it

00:38:17.280 --> 00:38:18.060
because you

00:38:18.060 --> 00:38:18.600
need to get

00:38:18.600 --> 00:38:19.340
100%

00:38:19.340 --> 00:38:19.940
correctness

00:38:19.940 --> 00:38:20.300
back

00:38:20.300 --> 00:38:21.080
so

00:38:21.080 --> 00:38:22.200
the S-team

00:38:22.200 --> 00:38:23.060
works slightly

00:38:23.060 --> 00:38:23.520
differently

00:38:23.520 --> 00:38:24.340
where you

00:38:24.340 --> 00:38:26.780
you essentially

00:38:26.780 --> 00:38:27.720
write programs

00:38:27.720 --> 00:38:28.220
in a mode

00:38:28.220 --> 00:38:28.460
where

00:38:28.460 --> 00:38:30.040
it looks like

00:38:30.040 --> 00:38:30.480
you put a

00:38:30.480 --> 00:38:31.540
gigantic lock

00:38:31.540 --> 00:38:32.140
around

00:38:32.140 --> 00:38:33.560
everything that

00:38:33.560 --> 00:38:34.160
matters in

00:38:34.160 --> 00:38:34.700
your program

00:38:34.700 --> 00:38:36.140
so you

00:38:36.140 --> 00:38:36.860
write one

00:38:36.860 --> 00:38:37.560
event loop

00:38:37.560 --> 00:38:38.080
and you know

00:38:38.080 --> 00:38:38.620
like okay

00:38:38.620 --> 00:38:40.000
this loop

00:38:40.000 --> 00:38:40.540
will

00:38:40.540 --> 00:38:42.320
consume blocks

00:38:42.320 --> 00:38:42.900
or whatever

00:38:42.900 --> 00:38:43.600
consume some

00:38:43.600 --> 00:38:44.240
sort of data

00:38:44.240 --> 00:38:45.900
in an unordered

00:38:45.900 --> 00:38:46.280
queue

00:38:46.280 --> 00:38:47.140
and you can

00:38:47.140 --> 00:38:47.800
add to the

00:38:47.800 --> 00:38:48.100
queue

00:38:48.100 --> 00:38:49.140
in an unordered

00:38:49.140 --> 00:38:49.460
way

00:38:49.460 --> 00:38:49.960
and then you

00:38:49.960 --> 00:38:50.480
put a giant

00:38:50.480 --> 00:38:50.840
lock

00:38:50.840 --> 00:38:51.880
over like

00:38:51.880 --> 00:38:52.160
the whole

00:38:52.160 --> 00:38:52.600
processing

00:38:52.600 --> 00:38:53.280
if you

00:38:53.280 --> 00:38:53.620
write that

00:38:53.620 --> 00:38:53.920
sort of

00:38:53.920 --> 00:38:54.220
program

00:38:54.220 --> 00:38:54.820
with normal

00:38:54.820 --> 00:38:55.460
threads

00:38:55.460 --> 00:38:55.900
and normal

00:38:55.900 --> 00:38:56.340
locks

00:38:56.340 --> 00:38:57.260
it will

00:38:57.260 --> 00:38:58.220
it will

00:38:58.220 --> 00:38:58.840
be correct

00:38:58.840 --> 00:38:59.200
but it

00:38:59.200 --> 00:38:59.580
won't run

00:38:59.580 --> 00:38:59.960
fast

00:38:59.960 --> 00:39:00.340
because

00:39:00.340 --> 00:39:00.980
everything

00:39:00.980 --> 00:39:01.380
will be

00:39:01.380 --> 00:39:01.640
giant

00:39:01.640 --> 00:39:02.560
will be

00:39:02.560 --> 00:39:02.920
inside

00:39:02.920 --> 00:39:03.340
the giant

00:39:03.340 --> 00:39:03.740
locks

00:39:03.740 --> 00:39:04.380
to be more

00:39:04.380 --> 00:39:04.660
or less

00:39:04.660 --> 00:39:05.100
serial

00:39:05.100 --> 00:39:05.940
but all

00:39:05.940 --> 00:39:06.580
the complexity

00:39:06.580 --> 00:39:06.960
in your

00:39:06.960 --> 00:39:07.180
code

00:39:07.180 --> 00:39:07.500
of doing

00:39:07.500 --> 00:39:08.060
parallelism

00:39:08.060 --> 00:39:08.440
anyway

00:39:08.440 --> 00:39:09.020
yeah

00:39:09.020 --> 00:39:09.440
so

00:39:09.440 --> 00:39:11.060
this

00:39:11.060 --> 00:39:11.540
so

00:39:11.540 --> 00:39:12.320
STM

00:39:12.320 --> 00:39:12.840
stands

00:39:12.840 --> 00:39:13.100
for

00:39:13.100 --> 00:39:13.420
software

00:39:13.420 --> 00:39:14.020
transactional

00:39:14.020 --> 00:39:14.400
memory

00:39:14.400 --> 00:39:15.260
it means

00:39:15.260 --> 00:39:15.900
it works

00:39:15.900 --> 00:39:16.200
roughly

00:39:16.200 --> 00:39:16.580
like a

00:39:16.580 --> 00:39:16.920
database

00:39:16.920 --> 00:39:17.820
where you

00:39:17.820 --> 00:39:18.900
run

00:39:18.900 --> 00:39:19.460
multiple

00:39:19.620 --> 00:39:20.140
transactions

00:39:20.140 --> 00:39:21.400
and then

00:39:21.400 --> 00:39:22.600
if you

00:39:22.600 --> 00:39:23.020
don't

00:39:23.020 --> 00:39:23.480
touch

00:39:23.480 --> 00:39:24.920
the memory

00:39:24.920 --> 00:39:26.720
from two

00:39:26.720 --> 00:39:27.060
threads

00:39:27.060 --> 00:39:27.380
at the

00:39:27.380 --> 00:39:27.580
same

00:39:27.580 --> 00:39:28.000
time

00:39:28.000 --> 00:39:28.380
then

00:39:28.380 --> 00:39:28.640
it's

00:39:28.640 --> 00:39:28.860
all

00:39:28.860 --> 00:39:29.160
cool

00:39:29.160 --> 00:39:29.820
and if

00:39:29.820 --> 00:39:29.920
you

00:39:29.920 --> 00:39:30.120
touch

00:39:30.120 --> 00:39:30.540
one of

00:39:30.540 --> 00:39:30.740
those

00:39:30.740 --> 00:39:30.940
gets

00:39:30.940 --> 00:39:31.400
aborted

00:39:31.400 --> 00:39:32.120
and reverted

00:39:32.120 --> 00:39:32.960
and you

00:39:32.960 --> 00:39:33.340
can only

00:39:33.340 --> 00:39:33.940
commit a

00:39:33.940 --> 00:39:34.420
transaction

00:39:34.420 --> 00:39:34.880
if

00:39:34.880 --> 00:39:35.780
the

00:39:35.780 --> 00:39:36.400
memory

00:39:36.400 --> 00:39:36.720
access

00:39:36.720 --> 00:39:36.960
was

00:39:36.960 --> 00:39:37.220
right

00:39:37.220 --> 00:39:37.460
so

00:39:37.460 --> 00:39:37.940
if

00:39:37.940 --> 00:39:38.040
you

00:39:38.040 --> 00:39:38.260
think

00:39:38.260 --> 00:39:38.540
again

00:39:38.540 --> 00:39:38.760
about

00:39:38.760 --> 00:39:38.920
the

00:39:38.920 --> 00:39:39.200
model

00:39:39.200 --> 00:39:39.560
where

00:39:39.560 --> 00:39:39.720
you

00:39:39.720 --> 00:39:39.880
have

00:39:39.880 --> 00:39:40.080
one

00:39:40.080 --> 00:39:40.500
gigantic

00:39:40.500 --> 00:39:40.820
log

00:39:40.820 --> 00:39:41.180
it means

00:39:41.180 --> 00:39:41.480
it will

00:39:41.480 --> 00:39:41.820
run

00:39:41.820 --> 00:39:42.900
in parallel

00:39:42.900 --> 00:39:43.940
optimistically

00:39:43.940 --> 00:39:44.640
a few

00:39:44.640 --> 00:39:45.580
versions

00:39:45.580 --> 00:39:45.900
of the

00:39:45.900 --> 00:39:46.120
same

00:39:46.120 --> 00:39:46.440
code

00:39:46.440 --> 00:39:46.600
on

00:39:46.600 --> 00:39:46.920
different

00:39:46.920 --> 00:39:47.400
data

00:39:47.400 --> 00:39:48.560
and if

00:39:48.560 --> 00:39:48.720
they

00:39:48.720 --> 00:39:49.260
tend

00:39:49.260 --> 00:39:49.840
not to

00:39:49.840 --> 00:39:50.320
conflict

00:39:50.320 --> 00:39:50.600
if

00:39:50.600 --> 00:39:51.500
they can

00:39:51.500 --> 00:39:51.840
be

00:39:51.840 --> 00:39:53.400
run

00:39:53.400 --> 00:39:54.080
serially

00:39:54.080 --> 00:39:54.520
in a

00:39:54.520 --> 00:39:54.900
sense

00:39:54.900 --> 00:39:55.520
like

00:39:55.520 --> 00:39:55.740
they

00:39:55.740 --> 00:39:56.080
modify

00:39:56.080 --> 00:39:56.320
some

00:39:56.320 --> 00:39:56.560
global

00:39:56.560 --> 00:39:56.860
data

00:39:56.860 --> 00:39:57.040
but

00:39:57.040 --> 00:39:57.400
not

00:39:57.400 --> 00:39:57.660
in a

00:39:57.660 --> 00:39:58.100
conflicting

00:39:58.100 --> 00:39:58.460
manner

00:39:58.460 --> 00:40:00.100
then

00:40:00.100 --> 00:40:01.860
you'll

00:40:01.860 --> 00:40:02.160
get

00:40:02.160 --> 00:40:03.100
parallelism

00:40:03.100 --> 00:40:04.140
for free

00:40:04.140 --> 00:40:05.020
but if

00:40:05.020 --> 00:40:05.380
they do

00:40:05.380 --> 00:40:05.820
conflict

00:40:05.820 --> 00:40:06.340
every now

00:40:06.340 --> 00:40:06.720
and again

00:40:06.720 --> 00:40:07.040
then

00:40:07.040 --> 00:40:08.640
one of

00:40:08.640 --> 00:40:09.000
the guys

00:40:09.000 --> 00:40:09.360
gets

00:40:09.360 --> 00:40:10.280
reverted

00:40:10.280 --> 00:40:10.800
back to

00:40:10.800 --> 00:40:11.240
the start

00:40:11.240 --> 00:40:12.360
so the

00:40:12.360 --> 00:40:12.800
net effect

00:40:12.800 --> 00:40:13.180
is that

00:40:13.180 --> 00:40:14.280
it looks

00:40:14.280 --> 00:40:14.680
like you're

00:40:14.680 --> 00:40:14.960
running

00:40:14.960 --> 00:40:15.280
stuff

00:40:15.280 --> 00:40:15.780
serially

00:40:15.780 --> 00:40:16.260
for the

00:40:16.260 --> 00:40:16.640
programmer

00:40:16.640 --> 00:40:17.180
and you

00:40:17.180 --> 00:40:17.480
get

00:40:17.480 --> 00:40:18.440
correctness

00:40:18.440 --> 00:40:18.960
for free

00:40:18.960 --> 00:40:19.920
if you

00:40:19.920 --> 00:40:20.640
write it

00:40:20.640 --> 00:40:21.400
in a

00:40:21.400 --> 00:40:21.700
way

00:40:21.700 --> 00:40:22.140
that

00:40:22.140 --> 00:40:24.340
that's

00:40:24.340 --> 00:40:24.740
naive

00:40:24.740 --> 00:40:25.320
then you

00:40:25.320 --> 00:40:25.700
won't get

00:40:25.700 --> 00:40:26.140
performance

00:40:26.140 --> 00:40:26.700
because your

00:40:26.700 --> 00:40:27.200
stuff will

00:40:27.200 --> 00:40:27.560
collide

00:40:27.560 --> 00:40:27.920
all the

00:40:27.920 --> 00:40:28.440
time

00:40:28.440 --> 00:40:28.860
but then

00:40:28.860 --> 00:40:29.160
you can

00:40:29.160 --> 00:40:29.440
use

00:40:29.440 --> 00:40:29.840
tools

00:40:29.840 --> 00:40:30.320
and look

00:40:30.320 --> 00:40:30.780
where it

00:40:30.780 --> 00:40:31.160
collides

00:40:31.160 --> 00:40:31.780
and remove

00:40:31.780 --> 00:40:32.060
those

00:40:32.060 --> 00:40:32.540
contention

00:40:32.540 --> 00:40:32.940
points

00:40:32.940 --> 00:40:33.400
and you

00:40:33.400 --> 00:40:33.800
get more

00:40:33.800 --> 00:40:34.060
and more

00:40:34.060 --> 00:40:34.580
performance

00:40:34.580 --> 00:40:35.660
which is

00:40:35.660 --> 00:40:36.740
almost the

00:40:36.740 --> 00:40:37.360
same goal

00:40:37.360 --> 00:40:38.020
but the

00:40:38.020 --> 00:40:38.420
difference

00:40:38.420 --> 00:40:38.900
is that

00:40:38.900 --> 00:40:39.240
if you

00:40:39.240 --> 00:40:39.560
have

00:40:39.560 --> 00:40:40.620
100%

00:40:40.620 --> 00:40:41.560
performance

00:40:41.560 --> 00:40:42.600
and 99%

00:40:42.600 --> 00:40:43.200
correctness

00:40:43.200 --> 00:40:43.660
your program

00:40:43.660 --> 00:40:44.080
is still

00:40:44.080 --> 00:40:44.480
incorrect

00:40:44.480 --> 00:40:44.860
and you

00:40:44.860 --> 00:40:45.340
can't run

00:40:45.340 --> 00:40:45.680
it

00:40:45.680 --> 00:40:46.160
if you

00:40:46.160 --> 00:40:46.320
have

00:40:46.320 --> 00:40:47.040
100%

00:40:47.040 --> 00:40:47.660
correctness

00:40:47.660 --> 00:40:48.540
and 99%

00:40:48.540 --> 00:40:49.060
performance

00:40:49.060 --> 00:40:49.460
you're

00:40:49.460 --> 00:40:49.780
mostly

00:40:49.780 --> 00:40:50.220
good to

00:40:50.220 --> 00:40:50.520
go

00:40:50.520 --> 00:40:51.100
yeah

00:40:51.100 --> 00:40:52.420
would you

00:40:52.420 --> 00:40:53.020
rather be

00:40:53.020 --> 00:40:54.000
fast and

00:40:54.000 --> 00:40:54.500
wrong or

00:40:54.500 --> 00:40:54.920
slow and

00:40:54.920 --> 00:40:55.160
right

00:40:55.160 --> 00:40:55.500
it's sort

00:40:55.500 --> 00:40:55.620
of

00:40:55.620 --> 00:40:56.820
that you

00:40:56.820 --> 00:40:56.900
know

00:40:56.900 --> 00:40:57.240
there's a

00:40:57.240 --> 00:40:57.400
really

00:40:57.400 --> 00:40:57.900
interesting

00:40:57.900 --> 00:40:59.400
classification

00:40:59.400 --> 00:41:00.400
of those

00:41:00.400 --> 00:41:00.760
types of

00:41:00.760 --> 00:41:01.160
problems

00:41:01.160 --> 00:41:01.480
that you

00:41:01.480 --> 00:41:02.340
only see

00:41:02.340 --> 00:41:02.900
every

00:41:02.900 --> 00:41:04.160
very very

00:41:04.160 --> 00:41:04.960
rarely

00:41:04.960 --> 00:41:05.760
from the

00:41:05.760 --> 00:41:06.480
you know

00:41:06.480 --> 00:41:06.740
sort of

00:41:06.740 --> 00:41:07.080
some kind

00:41:07.080 --> 00:41:07.440
of race

00:41:07.440 --> 00:41:07.840
condition

00:41:07.840 --> 00:41:08.440
or timing

00:41:08.440 --> 00:41:08.900
threading

00:41:08.900 --> 00:41:09.260
problem

00:41:09.260 --> 00:41:10.100
and I've

00:41:10.100 --> 00:41:10.400
heard people

00:41:10.400 --> 00:41:11.040
describe those

00:41:11.040 --> 00:41:11.960
as Heisen bugs

00:41:11.960 --> 00:41:13.160
because

00:41:13.160 --> 00:41:14.220
because as you

00:41:14.220 --> 00:41:14.660
interact with

00:41:14.660 --> 00:41:15.060
a program

00:41:15.060 --> 00:41:15.480
trying to

00:41:15.480 --> 00:41:15.800
see the

00:41:15.800 --> 00:41:16.100
problem

00:41:16.100 --> 00:41:16.520
you might

00:41:16.520 --> 00:41:17.020
not be

00:41:17.020 --> 00:41:17.280
able to

00:41:17.280 --> 00:41:17.720
observe it

00:41:17.720 --> 00:41:17.940
but if

00:41:17.940 --> 00:41:18.160
you're not

00:41:18.160 --> 00:41:18.420
looking

00:41:18.420 --> 00:41:18.780
all of a

00:41:18.780 --> 00:41:18.980
sudden

00:41:18.980 --> 00:41:19.300
boom

00:41:19.300 --> 00:41:19.460
the

00:41:19.460 --> 00:41:20.200
timing

00:41:20.200 --> 00:41:20.880
realigns

00:41:20.880 --> 00:41:21.140
and it's

00:41:21.140 --> 00:41:21.520
a problem

00:41:21.520 --> 00:41:21.860
again

00:41:21.860 --> 00:41:22.560
they're very

00:41:22.560 --> 00:41:22.920
frustrating

00:41:22.920 --> 00:41:23.460
so it's

00:41:23.460 --> 00:41:23.800
important

00:41:23.800 --> 00:41:24.320
to look

00:41:24.320 --> 00:41:24.720
at

00:41:24.720 --> 00:41:26.060
so that

00:41:26.060 --> 00:41:26.380
the

00:41:26.380 --> 00:41:26.760
usual

00:41:26.760 --> 00:41:27.200
answer

00:41:27.200 --> 00:41:27.580
for

00:41:27.580 --> 00:41:28.100
those

00:41:28.100 --> 00:41:28.580
problems

00:41:28.580 --> 00:41:28.780
in

00:41:28.780 --> 00:41:29.100
Python

00:41:29.100 --> 00:41:29.320
is

00:41:29.320 --> 00:41:29.680
just

00:41:29.680 --> 00:41:29.920
use

00:41:29.920 --> 00:41:30.300
multiple

00:41:30.300 --> 00:41:30.840
processes

00:41:30.840 --> 00:41:32.060
and using

00:41:32.060 --> 00:41:32.480
multiple

00:41:32.480 --> 00:41:33.000
processes

00:41:33.000 --> 00:41:33.800
works for a

00:41:33.800 --> 00:41:34.360
category of

00:41:34.360 --> 00:41:34.840
applications

00:41:34.840 --> 00:41:35.520
and web

00:41:35.520 --> 00:41:36.260
servers tend

00:41:36.260 --> 00:41:36.780
to be one

00:41:36.780 --> 00:41:37.100
of those

00:41:37.100 --> 00:41:37.580
because they

00:41:37.580 --> 00:41:38.420
only ever

00:41:38.420 --> 00:41:39.200
share data

00:41:39.200 --> 00:41:40.080
that's

00:41:40.080 --> 00:41:40.400
either

00:41:40.400 --> 00:41:40.840
caches

00:41:40.840 --> 00:41:42.260
or database

00:41:42.260 --> 00:41:43.060
usually

00:41:43.060 --> 00:41:43.340
that's

00:41:43.340 --> 00:41:43.780
another

00:41:43.780 --> 00:41:44.220
process

00:41:44.220 --> 00:41:44.520
anyway

00:41:44.520 --> 00:41:44.780
like

00:41:44.780 --> 00:41:45.240
Redis

00:41:45.240 --> 00:41:45.600
or

00:41:45.600 --> 00:41:45.860
it's

00:41:45.860 --> 00:41:46.040
in a

00:41:46.040 --> 00:41:46.280
database

00:41:46.280 --> 00:41:46.500
like

00:41:46.500 --> 00:41:46.820
Mongo

00:41:46.820 --> 00:41:47.080
or

00:41:47.080 --> 00:41:47.400
SQL

00:41:47.400 --> 00:41:47.740
or

00:41:47.740 --> 00:41:47.900
something

00:41:47.900 --> 00:41:48.060
like

00:41:48.060 --> 00:41:48.240
that

00:41:48.240 --> 00:41:48.420
yeah

00:41:48.420 --> 00:41:49.020
so

00:41:49.020 --> 00:41:49.220
you

00:41:49.220 --> 00:41:49.460
don't

00:41:49.460 --> 00:41:49.720
care

00:41:49.720 --> 00:41:50.220
but like

00:41:50.220 --> 00:41:50.700
there's a

00:41:50.700 --> 00:41:51.420
whole

00:41:51.420 --> 00:41:52.540
set of

00:41:52.540 --> 00:41:53.360
problems

00:41:53.360 --> 00:41:53.820
where

00:41:53.820 --> 00:41:55.240
this is not

00:41:55.240 --> 00:41:55.540
what you

00:41:55.540 --> 00:41:55.700
have

00:41:55.700 --> 00:41:55.980
you have

00:41:55.980 --> 00:41:56.340
data

00:41:56.340 --> 00:41:56.600
that's

00:41:56.600 --> 00:41:57.000
mostly

00:41:57.000 --> 00:41:57.240
not

00:41:57.240 --> 00:41:57.880
contentious

00:41:57.880 --> 00:41:58.160
but

00:41:58.160 --> 00:41:58.900
you still

00:41:58.900 --> 00:41:59.200
have to

00:41:59.200 --> 00:41:59.660
share it

00:41:59.660 --> 00:42:00.180
and work

00:42:00.180 --> 00:42:00.420
on it

00:42:00.420 --> 00:42:01.000
you can't

00:42:01.000 --> 00:42:01.440
afford

00:42:01.440 --> 00:42:02.100
to

00:42:02.100 --> 00:42:02.800
serialize

00:42:02.800 --> 00:42:03.700
and deserialize

00:42:03.700 --> 00:42:04.040
and pass

00:42:04.040 --> 00:42:04.360
between

00:42:04.360 --> 00:42:05.600
processes

00:42:05.600 --> 00:42:07.020
and yet

00:42:07.020 --> 00:42:07.420
you want

00:42:07.420 --> 00:42:07.920
to have

00:42:07.920 --> 00:42:09.460
a correct

00:42:09.460 --> 00:42:10.180
result

00:42:10.180 --> 00:42:10.740
so this

00:42:10.740 --> 00:42:11.020
is what

00:42:11.020 --> 00:42:11.400
STM

00:42:11.400 --> 00:42:11.720
is trying

00:42:11.720 --> 00:42:12.200
to address

00:42:12.200 --> 00:42:13.720
a set

00:42:13.720 --> 00:42:14.220
of problems

00:42:14.220 --> 00:42:14.740
that can

00:42:14.740 --> 00:42:15.280
be solved

00:42:15.280 --> 00:42:16.080
by just

00:42:16.080 --> 00:42:16.460
splitting

00:42:16.460 --> 00:42:16.760
stuff

00:42:16.760 --> 00:42:16.960
into

00:42:16.960 --> 00:42:17.440
processes

00:42:17.440 --> 00:42:18.600
right

00:42:18.600 --> 00:42:19.060
maybe

00:42:19.060 --> 00:42:19.380
something

00:42:19.380 --> 00:42:19.620
very

00:42:19.620 --> 00:42:20.240
computational

00:42:20.240 --> 00:42:21.020
or scientific

00:42:21.020 --> 00:42:21.820
where it's

00:42:21.820 --> 00:42:22.260
iterative

00:42:22.260 --> 00:42:22.740
or something

00:42:22.740 --> 00:42:23.580
would be

00:42:23.580 --> 00:42:24.080
way harder

00:42:24.080 --> 00:42:25.460
well

00:42:25.460 --> 00:42:26.300
essentially

00:42:26.300 --> 00:42:26.840
anything

00:42:26.840 --> 00:42:27.280
where

00:42:27.280 --> 00:42:28.200
you have

00:42:28.200 --> 00:42:28.560
data

00:42:28.560 --> 00:42:28.780
that

00:42:28.780 --> 00:42:29.300
mostly

00:42:29.300 --> 00:42:29.760
does not

00:42:29.760 --> 00:42:30.200
conflict

00:42:30.200 --> 00:42:30.540
and you

00:42:30.540 --> 00:42:30.880
can do

00:42:30.880 --> 00:42:31.420
it

00:42:31.420 --> 00:42:31.920
in

00:42:31.920 --> 00:42:32.660
parallel

00:42:32.660 --> 00:42:33.000
but

00:42:33.000 --> 00:42:33.780
every now

00:42:33.780 --> 00:42:34.040
and again

00:42:34.040 --> 00:42:34.720
it's a

00:42:34.720 --> 00:42:35.200
big data

00:42:35.200 --> 00:42:35.420
set

00:42:35.420 --> 00:42:35.740
that you

00:42:35.740 --> 00:42:36.120
work on

00:42:36.120 --> 00:42:36.480
and every

00:42:36.480 --> 00:42:36.780
now and

00:42:36.780 --> 00:42:37.040
again

00:42:37.040 --> 00:42:37.560
you

00:42:37.560 --> 00:42:38.560
tend

00:42:38.560 --> 00:42:38.880
to

00:42:38.880 --> 00:42:39.540
conflict

00:42:39.540 --> 00:42:39.960
like

00:42:39.960 --> 00:42:41.020
graph

00:42:41.020 --> 00:42:41.640
algorithms

00:42:41.640 --> 00:42:41.820
are a

00:42:41.820 --> 00:42:42.040
great

00:42:42.040 --> 00:42:42.420
example

00:42:42.420 --> 00:42:42.700
and you

00:42:42.700 --> 00:42:42.980
have this

00:42:42.980 --> 00:42:43.500
large

00:42:43.500 --> 00:42:44.080
complicated

00:42:44.080 --> 00:42:44.440
data

00:42:44.440 --> 00:42:44.800
structure

00:42:44.800 --> 00:42:45.320
in memory

00:42:45.320 --> 00:42:46.180
and most

00:42:46.180 --> 00:42:46.540
of the time

00:42:46.540 --> 00:42:47.040
you're walking

00:42:47.040 --> 00:42:48.120
different parts

00:42:48.120 --> 00:42:48.540
of graphs

00:42:48.540 --> 00:42:49.020
so you don't

00:42:49.020 --> 00:42:49.440
care

00:42:49.440 --> 00:42:50.840
but every

00:42:50.840 --> 00:42:51.320
now and again

00:42:51.320 --> 00:42:52.420
you'll find

00:42:52.420 --> 00:42:52.960
contention

00:42:52.960 --> 00:42:53.620
on one graph

00:42:53.620 --> 00:42:54.400
because two

00:42:54.400 --> 00:42:55.560
parts are doing

00:42:55.560 --> 00:42:56.780
stuff on the

00:42:56.780 --> 00:42:57.260
same node

00:42:57.260 --> 00:42:57.760
and then you're

00:42:57.760 --> 00:42:57.960
like

00:42:57.960 --> 00:42:59.120
that's wrong

00:42:59.120 --> 00:42:59.540
and writing

00:42:59.540 --> 00:43:00.080
this sort of

00:43:00.080 --> 00:43:00.560
stuff using

00:43:00.560 --> 00:43:00.920
threads

00:43:00.920 --> 00:43:01.340
is really

00:43:01.340 --> 00:43:01.700
hard

00:43:01.700 --> 00:43:02.900
yeah

00:43:02.900 --> 00:43:03.380
so that

00:43:03.380 --> 00:43:03.900
has a lot

00:43:03.900 --> 00:43:04.300
of promise

00:43:04.300 --> 00:43:04.880
do you know

00:43:04.880 --> 00:43:05.380
when it

00:43:05.380 --> 00:43:05.880
might

00:43:05.880 --> 00:43:06.720
start to

00:43:06.720 --> 00:43:07.000
show up

00:43:07.000 --> 00:43:07.440
as a thing

00:43:07.440 --> 00:43:07.940
people can

00:43:07.940 --> 00:43:08.220
use

00:43:08.220 --> 00:43:09.120
is it

00:43:09.120 --> 00:43:09.500
there yet

00:43:09.500 --> 00:43:10.800
so it's

00:43:10.800 --> 00:43:11.600
already there

00:43:11.600 --> 00:43:12.420
to an extent

00:43:12.420 --> 00:43:13.360
you can

00:43:13.360 --> 00:43:14.400
download the

00:43:14.400 --> 00:43:15.160
STM demo

00:43:15.160 --> 00:43:15.620
somewhere

00:43:15.620 --> 00:43:16.620
and the

00:43:16.620 --> 00:43:17.240
STM demo

00:43:17.240 --> 00:43:17.840
works

00:43:17.840 --> 00:43:19.300
it might

00:43:19.300 --> 00:43:20.120
not scale

00:43:20.120 --> 00:43:20.720
how you want

00:43:20.720 --> 00:43:20.860
it

00:43:20.860 --> 00:43:21.160
it might

00:43:21.160 --> 00:43:21.660
not work

00:43:21.660 --> 00:43:21.980
how you

00:43:21.980 --> 00:43:22.200
want

00:43:22.200 --> 00:43:22.380
it

00:43:22.380 --> 00:43:22.880
but it

00:43:22.880 --> 00:43:23.140
should

00:43:23.140 --> 00:43:23.580
generally

00:43:23.580 --> 00:43:23.980
work

00:43:23.980 --> 00:43:24.520
and scale

00:43:24.520 --> 00:43:25.640
so the

00:43:25.640 --> 00:43:26.320
current version

00:43:26.320 --> 00:43:27.360
only scales

00:43:27.360 --> 00:43:27.940
to like

00:43:27.940 --> 00:43:29.380
two or three

00:43:29.380 --> 00:43:30.540
cores

00:43:30.540 --> 00:43:32.060
and given

00:43:32.060 --> 00:43:32.460
that it

00:43:32.460 --> 00:43:32.880
comes at

00:43:32.880 --> 00:43:33.640
a quite

00:43:33.640 --> 00:43:34.580
hefty cost

00:43:34.580 --> 00:43:35.060
of like

00:43:35.060 --> 00:43:36.520
1.5

00:43:36.520 --> 00:43:37.200
to two

00:43:37.200 --> 00:43:38.020
times slower

00:43:38.020 --> 00:43:38.620
on each

00:43:38.620 --> 00:43:38.880
core

00:43:38.880 --> 00:43:39.420
it's not

00:43:39.420 --> 00:43:40.240
that useful

00:43:40.240 --> 00:43:41.260
so the

00:43:41.260 --> 00:43:41.900
next version

00:43:41.900 --> 00:43:42.500
will try to

00:43:42.500 --> 00:43:43.160
reduce the

00:43:43.160 --> 00:43:43.800
overhead of

00:43:43.800 --> 00:43:44.500
single core

00:43:44.500 --> 00:43:45.180
and improve

00:43:45.180 --> 00:43:46.100
the scalability

00:43:46.100 --> 00:43:46.580
to more

00:43:46.580 --> 00:43:46.920
cores

00:43:46.920 --> 00:43:47.380
and then

00:43:47.380 --> 00:43:47.840
we'll see

00:43:47.840 --> 00:43:48.160
how it

00:43:48.160 --> 00:43:48.420
goes

00:43:48.420 --> 00:43:49.440
it's going

00:43:49.440 --> 00:43:50.080
along quite

00:43:50.080 --> 00:43:50.420
well

00:43:50.420 --> 00:43:50.840
I would

00:43:50.840 --> 00:43:51.260
expect

00:43:51.260 --> 00:43:51.720
like

00:43:51.720 --> 00:43:52.740
I mean

00:43:52.740 --> 00:43:54.160
there are

00:43:54.160 --> 00:43:54.780
consecutive

00:43:54.780 --> 00:43:55.300
prototypes

00:43:55.300 --> 00:43:55.860
that are

00:43:55.860 --> 00:43:56.440
usable

00:43:56.440 --> 00:43:57.040
to some

00:43:57.040 --> 00:43:57.340
extent

00:43:57.340 --> 00:43:57.860
like we

00:43:57.860 --> 00:43:58.440
managed to

00:43:58.440 --> 00:43:58.680
get

00:43:58.680 --> 00:43:59.600
some

00:43:59.600 --> 00:44:00.160
performance

00:44:00.160 --> 00:44:00.640
improvements

00:44:00.640 --> 00:44:01.140
running

00:44:01.140 --> 00:44:02.040
on multiple

00:44:02.040 --> 00:44:02.440
cores

00:44:02.440 --> 00:44:02.800
but they

00:44:02.800 --> 00:44:02.940
have

00:44:02.940 --> 00:44:04.360
20-30%

00:44:04.360 --> 00:44:04.720
range

00:44:04.720 --> 00:44:05.200
which is

00:44:05.200 --> 00:44:06.240
just not

00:44:06.240 --> 00:44:06.840
that exciting

00:44:06.840 --> 00:44:07.680
but on the

00:44:07.680 --> 00:44:08.000
other hand

00:44:08.000 --> 00:44:08.300
they were

00:44:08.300 --> 00:44:08.940
mostly for

00:44:08.940 --> 00:44:09.320
free

00:44:09.320 --> 00:44:10.900
which is

00:44:10.900 --> 00:44:11.160
again

00:44:11.160 --> 00:44:11.780
something

00:44:11.780 --> 00:44:12.220
that you

00:44:12.220 --> 00:44:13.860
might

00:44:13.860 --> 00:44:15.920
what if

00:44:15.920 --> 00:44:16.460
I rewrite

00:44:16.460 --> 00:44:16.940
no no

00:44:16.940 --> 00:44:17.240
the point

00:44:17.240 --> 00:44:17.460
is you

00:44:17.460 --> 00:44:17.760
don't have

00:44:17.760 --> 00:44:18.200
to rewrite

00:44:18.200 --> 00:44:18.900
it's

00:44:18.900 --> 00:44:19.360
a very

00:44:19.360 --> 00:44:19.660
simple

00:44:19.660 --> 00:44:20.000
change

00:44:20.000 --> 00:44:20.380
and then

00:44:20.380 --> 00:44:20.660
you might

00:44:20.660 --> 00:44:20.880
get

00:44:20.880 --> 00:44:21.540
some

00:44:21.540 --> 00:44:22.140
performance

00:44:22.140 --> 00:44:22.580
benefit

00:44:22.580 --> 00:44:22.840
yeah

00:44:22.840 --> 00:44:23.100
that's

00:44:23.100 --> 00:44:23.500
fantastic

00:44:23.500 --> 00:44:24.900
the other

00:44:24.900 --> 00:44:25.700
one of the

00:44:25.700 --> 00:44:25.940
other

00:44:25.940 --> 00:44:26.620
projects

00:44:26.620 --> 00:44:27.140
that you

00:44:27.140 --> 00:44:27.640
have

00:44:27.640 --> 00:44:28.100
on your

00:44:28.100 --> 00:44:28.500
donation

00:44:28.500 --> 00:44:28.800
list

00:44:28.800 --> 00:44:29.060
is a

00:44:29.060 --> 00:44:29.220
major

00:44:29.220 --> 00:44:29.420
thing

00:44:29.420 --> 00:44:29.740
you guys

00:44:29.740 --> 00:44:29.840
are

00:44:29.840 --> 00:44:30.100
working

00:44:30.100 --> 00:44:30.380
on

00:44:30.380 --> 00:44:30.880
is

00:44:30.880 --> 00:44:32.100
Pi3k

00:44:32.100 --> 00:44:32.540
in

00:44:32.540 --> 00:44:32.940
PiPi

00:44:32.940 --> 00:44:33.260
what's

00:44:33.260 --> 00:44:33.500
that

00:44:33.500 --> 00:44:34.960
it's

00:44:34.960 --> 00:44:35.180
the

00:44:35.180 --> 00:44:35.760
Python 3

00:44:35.760 --> 00:44:36.280
implementation

00:44:36.280 --> 00:44:36.480
of

00:44:36.480 --> 00:44:36.820
PiPi

00:44:36.820 --> 00:44:37.160
so

00:44:37.160 --> 00:44:38.600
as I

00:44:38.600 --> 00:44:38.800
said

00:44:38.800 --> 00:44:39.260
before

00:44:39.260 --> 00:44:40.180
we

00:44:40.180 --> 00:44:40.740
have

00:44:40.740 --> 00:44:41.180
various

00:44:41.180 --> 00:44:41.900
interpreters

00:44:41.900 --> 00:44:43.140
in

00:44:43.140 --> 00:44:44.100
PiPi

00:44:44.100 --> 00:44:44.880
that are

00:44:44.880 --> 00:44:45.640
all

00:44:45.640 --> 00:44:46.040
implemented

00:44:46.040 --> 00:44:46.340
in our

00:44:46.340 --> 00:44:46.640
Python

00:44:46.640 --> 00:44:47.040
and one

00:44:47.040 --> 00:44:47.460
of those

00:44:47.460 --> 00:44:48.060
interpreters

00:44:48.060 --> 00:44:48.320
is a

00:44:48.320 --> 00:44:48.840
Python 2

00:44:48.840 --> 00:44:49.240
interpreter

00:44:49.240 --> 00:44:49.780
and one

00:44:49.780 --> 00:44:50.100
of those

00:44:50.100 --> 00:44:50.640
interpreters

00:44:50.640 --> 00:44:51.120
which is

00:44:51.120 --> 00:44:52.260
less

00:44:52.260 --> 00:44:52.840
complete

00:44:52.840 --> 00:44:53.720
is Python 3

00:44:53.720 --> 00:44:54.320
interpreter

00:44:54.320 --> 00:44:55.160
that supports

00:44:55.160 --> 00:44:55.520
like

00:44:55.520 --> 00:44:56.420
3.2

00:44:56.420 --> 00:44:56.900
by now

00:44:56.900 --> 00:44:57.500
so

00:44:57.500 --> 00:44:58.120
we need

00:44:58.120 --> 00:44:58.400
money

00:44:58.400 --> 00:44:59.000
to push

00:44:59.000 --> 00:44:59.600
it forward

00:44:59.600 --> 00:45:00.420
and help

00:45:00.420 --> 00:45:00.800
I guess

00:45:00.800 --> 00:45:01.080
too

00:45:01.080 --> 00:45:01.740
to push

00:45:01.740 --> 00:45:02.140
it forward

00:45:02.140 --> 00:45:02.520
to like

00:45:02.520 --> 00:45:03.280
3.3

00:45:03.280 --> 00:45:04.420
or 3.4

00:45:04.420 --> 00:45:05.420
or even

00:45:05.420 --> 00:45:06.340
3.5

00:45:06.340 --> 00:45:08.040
to bring

00:45:08.040 --> 00:45:08.400
it more

00:45:08.400 --> 00:45:08.740
up to

00:45:08.740 --> 00:45:09.100
speed

00:45:09.100 --> 00:45:10.140
one thing

00:45:10.140 --> 00:45:10.480
that we

00:45:10.480 --> 00:45:11.100
don't do

00:45:11.100 --> 00:45:11.260
in

00:45:11.260 --> 00:45:11.660
PiPi

00:45:11.660 --> 00:45:12.140
is we

00:45:12.140 --> 00:45:12.700
don't

00:45:12.700 --> 00:45:13.140
debate

00:45:13.140 --> 00:45:13.400
the

00:45:13.400 --> 00:45:13.980
Python

00:45:13.980 --> 00:45:14.380
language

00:45:14.380 --> 00:45:15.000
choices

00:45:15.000 --> 00:45:15.660
and I

00:45:15.660 --> 00:45:16.020
think it

00:45:16.020 --> 00:45:16.240
serves

00:45:16.240 --> 00:45:16.460
us

00:45:16.460 --> 00:45:16.720
well

00:45:16.720 --> 00:45:17.360
so

00:45:17.360 --> 00:45:17.740
for

00:45:17.740 --> 00:45:18.040
example

00:45:18.040 --> 00:45:18.340
I

00:45:18.340 --> 00:45:18.620
don't

00:45:18.620 --> 00:45:18.920
work

00:45:18.920 --> 00:45:19.260
much

00:45:19.260 --> 00:45:19.500
on

00:45:19.500 --> 00:45:19.640
the

00:45:19.640 --> 00:45:19.920
Python

00:45:19.920 --> 00:45:20.440
interpreter

00:45:20.440 --> 00:45:20.920
itself

00:45:20.920 --> 00:45:21.100
I

00:45:21.100 --> 00:45:21.360
work

00:45:21.360 --> 00:45:21.660
a lot

00:45:21.660 --> 00:45:21.840
on

00:45:21.840 --> 00:45:22.200
the

00:45:22.200 --> 00:45:22.720
R

00:45:22.720 --> 00:45:22.960
Python

00:45:22.960 --> 00:45:23.260
side

00:45:23.260 --> 00:45:23.420
of

00:45:23.420 --> 00:45:23.740
things

00:45:23.740 --> 00:45:24.000
and

00:45:24.000 --> 00:45:24.260
most

00:45:24.260 --> 00:45:24.400
of

00:45:24.400 --> 00:45:24.500
the

00:45:24.500 --> 00:45:25.040
improvements

00:45:25.040 --> 00:45:25.680
help

00:45:25.680 --> 00:45:26.060
all

00:45:26.060 --> 00:45:26.920
of the

00:45:26.920 --> 00:45:27.400
interpreters

00:45:27.400 --> 00:45:27.740
not

00:45:27.740 --> 00:45:28.180
just

00:45:28.180 --> 00:45:30.060
Python

00:45:30.060 --> 00:45:30.540
interpreter

00:45:30.540 --> 00:45:31.100
so

00:45:31.100 --> 00:45:31.800
I

00:45:31.800 --> 00:45:32.260
personally

00:45:32.260 --> 00:45:32.780
don't care

00:45:32.780 --> 00:45:33.060
if it's

00:45:33.060 --> 00:45:33.460
Python 2

00:45:33.460 --> 00:45:34.100
or Python 3

00:45:34.100 --> 00:45:34.660
the improvements

00:45:34.660 --> 00:45:35.220
are all the

00:45:35.220 --> 00:45:35.840
same to me

00:45:35.840 --> 00:45:36.420
right

00:45:36.420 --> 00:45:36.660
that's

00:45:36.660 --> 00:45:36.880
great

00:45:36.880 --> 00:45:37.920
then you

00:45:37.920 --> 00:45:38.100
also

00:45:38.100 --> 00:45:38.580
have a

00:45:38.580 --> 00:45:39.280
section

00:45:39.280 --> 00:45:39.640
towards

00:45:39.640 --> 00:45:40.120
general

00:45:40.120 --> 00:45:40.800
progress

00:45:40.800 --> 00:45:41.040
and

00:45:41.040 --> 00:45:41.260
the

00:45:41.260 --> 00:45:41.500
last

00:45:41.500 --> 00:45:41.660
one

00:45:41.660 --> 00:45:41.820
is

00:45:41.820 --> 00:45:42.480
NumPy

00:45:42.480 --> 00:45:43.240
what are

00:45:43.240 --> 00:45:43.280
you

00:45:43.280 --> 00:45:43.840
trying to

00:45:43.840 --> 00:45:44.140
accomplish

00:45:44.140 --> 00:45:44.360
with

00:45:44.360 --> 00:45:44.600
that

00:45:44.600 --> 00:45:46.380
sprint

00:45:46.380 --> 00:45:46.680
or

00:45:46.680 --> 00:45:46.880
whatever

00:45:46.880 --> 00:45:47.000
you

00:45:47.000 --> 00:45:47.180
call

00:45:47.180 --> 00:45:48.240
it

00:45:48.240 --> 00:45:49.080
so

00:45:49.080 --> 00:45:49.540
as I

00:45:49.540 --> 00:45:49.700
said

00:45:49.700 --> 00:45:49.980
before

00:45:49.980 --> 00:45:50.380
the

00:45:50.380 --> 00:45:50.800
NumPy

00:45:50.800 --> 00:45:51.160
stuff

00:45:51.160 --> 00:45:51.600
is we

00:45:51.600 --> 00:45:52.060
want to

00:45:52.060 --> 00:45:52.700
reimplement

00:45:52.700 --> 00:45:52.920
the

00:45:52.920 --> 00:45:53.240
NumPy

00:45:53.240 --> 00:45:53.620
so the

00:45:53.620 --> 00:45:54.320
numeric

00:45:54.320 --> 00:45:54.740
part

00:45:54.740 --> 00:45:55.400
the

00:45:55.400 --> 00:45:55.820
operation

00:45:55.820 --> 00:45:56.080
on

00:45:56.080 --> 00:45:56.600
arrays

00:45:56.600 --> 00:45:56.960
and we

00:45:56.960 --> 00:45:57.100
have

00:45:57.100 --> 00:45:58.100
a very

00:45:58.100 --> 00:45:58.540
exciting

00:45:58.540 --> 00:45:59.760
project

00:45:59.760 --> 00:46:01.080
for

00:46:01.080 --> 00:46:01.440
summer

00:46:01.440 --> 00:46:01.640
of

00:46:01.640 --> 00:46:01.860
code

00:46:01.860 --> 00:46:02.080
that

00:46:02.080 --> 00:46:02.320
does

00:46:02.320 --> 00:46:03.020
vectorization

00:46:03.020 --> 00:46:03.460
so using

00:46:03.460 --> 00:46:03.860
SSE

00:46:03.860 --> 00:46:04.440
for

00:46:04.440 --> 00:46:05.500
NumPy

00:46:05.500 --> 00:46:06.940
and then

00:46:06.940 --> 00:46:07.460
we want

00:46:07.460 --> 00:46:08.200
to integrate

00:46:08.200 --> 00:46:08.940
more of

00:46:08.940 --> 00:46:09.600
the

00:46:09.600 --> 00:46:11.720
have a

00:46:11.720 --> 00:46:12.320
way to

00:46:12.320 --> 00:46:12.680
call

00:46:12.680 --> 00:46:13.280
more of

00:46:13.280 --> 00:46:13.720
the

00:46:13.720 --> 00:46:15.160
whole

00:46:15.160 --> 00:46:15.720
ecosystem

00:46:15.720 --> 00:46:16.140
of

00:46:16.140 --> 00:46:16.520
numeric

00:46:16.520 --> 00:46:16.840
Python

00:46:16.840 --> 00:46:17.200
so

00:46:17.200 --> 00:46:17.760
scipy

00:46:17.760 --> 00:46:18.120
mat

00:46:18.120 --> 00:46:18.340
world

00:46:18.340 --> 00:46:18.640
lib

00:46:18.640 --> 00:46:18.960
all

00:46:18.960 --> 00:46:19.400
this

00:46:19.400 --> 00:46:19.740
stuff

00:46:19.740 --> 00:46:20.100
that's

00:46:20.100 --> 00:46:20.540
outside

00:46:20.540 --> 00:46:20.720
of

00:46:20.720 --> 00:46:20.840
the

00:46:20.840 --> 00:46:21.080
scope

00:46:21.080 --> 00:46:21.400
so we

00:46:21.400 --> 00:46:21.620
want

00:46:21.620 --> 00:46:21.720
to

00:46:21.720 --> 00:46:21.900
have

00:46:21.900 --> 00:46:22.300
the

00:46:22.300 --> 00:46:22.540
core

00:46:22.540 --> 00:46:22.700
of

00:46:22.700 --> 00:46:23.020
NumPy

00:46:23.020 --> 00:46:23.580
implemented

00:46:23.580 --> 00:46:23.840
in

00:46:23.840 --> 00:46:24.200
PyPy

00:46:24.200 --> 00:46:24.500
because

00:46:24.500 --> 00:46:24.940
those

00:46:24.940 --> 00:46:25.320
things

00:46:25.320 --> 00:46:25.520
are

00:46:25.520 --> 00:46:25.780
too

00:46:25.780 --> 00:46:26.060
low

00:46:26.060 --> 00:46:26.400
level

00:46:26.400 --> 00:46:26.700
to

00:46:26.700 --> 00:46:27.380
just

00:46:27.380 --> 00:46:27.600
call

00:46:27.600 --> 00:46:27.940
external

00:46:27.940 --> 00:46:28.400
library

00:46:28.400 --> 00:46:29.280
and

00:46:29.280 --> 00:46:29.580
then

00:46:29.580 --> 00:46:29.800
we

00:46:29.800 --> 00:46:30.140
want

00:46:30.140 --> 00:46:30.320
to

00:46:30.320 --> 00:46:30.700
have

00:46:30.700 --> 00:46:31.540
a

00:46:31.540 --> 00:46:31.940
way

00:46:31.940 --> 00:46:32.400
or

00:46:32.400 --> 00:46:33.060
multiple

00:46:33.060 --> 00:46:33.440
ways

00:46:33.440 --> 00:46:33.780
depending

00:46:33.780 --> 00:46:34.060
on

00:46:34.060 --> 00:46:34.440
the

00:46:34.440 --> 00:46:34.780
setup

00:46:34.780 --> 00:46:35.080
to

00:46:35.080 --> 00:46:35.580
call

00:46:35.580 --> 00:46:36.160
all

00:46:36.160 --> 00:46:36.320
the

00:46:36.320 --> 00:46:36.560
other

00:46:36.560 --> 00:46:37.100
ecosystem

00:46:37.100 --> 00:46:37.660
and

00:46:37.660 --> 00:46:38.820
this

00:46:38.820 --> 00:46:38.940
is

00:46:38.940 --> 00:46:39.340
essentially

00:46:39.340 --> 00:46:39.580
what

00:46:39.580 --> 00:46:39.840
those

00:46:39.840 --> 00:46:40.220
goals

00:46:40.220 --> 00:46:40.560
are

00:46:40.560 --> 00:46:40.940
here

00:46:40.940 --> 00:46:42.440
those

00:46:42.440 --> 00:46:42.640
are

00:46:42.640 --> 00:46:43.160
three

00:46:43.160 --> 00:46:43.680
ambitious

00:46:43.680 --> 00:46:44.060
and

00:46:44.060 --> 00:46:44.380
very

00:46:44.380 --> 00:46:44.640
cool

00:46:44.640 --> 00:46:45.020
goals

00:46:45.020 --> 00:46:45.540
very

00:46:45.540 --> 00:46:45.800
nice

00:46:45.800 --> 00:46:46.600
well

00:46:46.600 --> 00:46:46.820
they've

00:46:46.820 --> 00:46:46.960
been

00:46:46.960 --> 00:46:47.280
around

00:46:47.280 --> 00:46:47.480
for

00:46:47.480 --> 00:46:47.600
a

00:46:47.600 --> 00:46:47.780
couple

00:46:47.780 --> 00:46:48.140
years

00:46:48.140 --> 00:46:48.380
I

00:46:48.380 --> 00:46:49.060
think

00:46:49.060 --> 00:46:49.980
so

00:46:49.980 --> 00:46:50.200
we

00:46:50.200 --> 00:46:50.320
are

00:46:50.320 --> 00:46:50.660
working

00:46:50.660 --> 00:46:51.080
towards

00:46:51.080 --> 00:46:51.380
them

00:46:51.380 --> 00:46:52.140
and

00:46:52.140 --> 00:46:52.260
we

00:46:52.260 --> 00:46:52.420
have

00:46:52.420 --> 00:46:52.720
people

00:46:52.720 --> 00:46:53.140
working

00:46:53.140 --> 00:46:53.420
right

00:46:53.420 --> 00:46:53.640
now

00:46:53.640 --> 00:46:53.860
on

00:46:53.860 --> 00:46:54.360
all

00:46:54.360 --> 00:46:54.600
three

00:46:54.600 --> 00:46:55.140
proposals

00:46:55.140 --> 00:46:55.740
as far

00:46:55.740 --> 00:46:56.000
as I

00:46:56.000 --> 00:46:56.140
can

00:46:56.140 --> 00:46:56.500
tell

00:46:56.500 --> 00:46:57.380
yeah

00:46:57.380 --> 00:46:57.700
that's

00:46:57.700 --> 00:46:57.880
great

00:46:57.880 --> 00:46:58.820
so

00:46:58.820 --> 00:46:59.240
one

00:46:59.240 --> 00:46:59.460
thing

00:46:59.460 --> 00:46:59.680
that

00:46:59.680 --> 00:47:00.140
is

00:47:00.140 --> 00:47:00.500
related

00:47:00.500 --> 00:47:00.680
to

00:47:00.680 --> 00:47:00.980
PyPy

00:47:00.980 --> 00:47:01.160
that

00:47:01.160 --> 00:47:01.440
you've

00:47:01.440 --> 00:47:01.820
done

00:47:01.820 --> 00:47:02.720
individually

00:47:02.720 --> 00:47:03.280
is

00:47:03.280 --> 00:47:03.620
the

00:47:03.620 --> 00:47:04.720
JIT

00:47:04.720 --> 00:47:05.000
viewer

00:47:05.000 --> 00:47:05.980
can you

00:47:05.980 --> 00:47:06.140
talk

00:47:06.140 --> 00:47:06.300
about

00:47:06.300 --> 00:47:06.440
that

00:47:06.440 --> 00:47:06.760
briefly

00:47:06.760 --> 00:47:08.060
so

00:47:08.060 --> 00:47:08.680
JIT

00:47:08.680 --> 00:47:08.880
viewer

00:47:08.880 --> 00:47:09.100
is

00:47:09.100 --> 00:47:09.260
a

00:47:09.260 --> 00:47:09.460
bit

00:47:09.460 --> 00:47:09.640
of

00:47:09.640 --> 00:47:09.800
an

00:47:09.800 --> 00:47:10.160
internal

00:47:10.160 --> 00:47:10.800
tool

00:47:10.800 --> 00:47:12.020
for

00:47:12.020 --> 00:47:13.660
visualizing

00:47:13.660 --> 00:47:14.520
assembler

00:47:14.520 --> 00:47:15.200
and the

00:47:15.200 --> 00:47:15.780
intermediate

00:47:15.780 --> 00:47:16.420
representation

00:47:16.420 --> 00:47:17.220
of

00:47:17.220 --> 00:47:18.360
your

00:47:18.360 --> 00:47:18.700
Python

00:47:18.700 --> 00:47:19.100
program

00:47:19.100 --> 00:47:19.320
so

00:47:19.320 --> 00:47:19.460
it's

00:47:19.460 --> 00:47:19.680
very

00:47:19.680 --> 00:47:20.000
useful

00:47:20.000 --> 00:47:20.300
for

00:47:20.300 --> 00:47:20.860
if

00:47:20.860 --> 00:47:21.080
you're

00:47:21.080 --> 00:47:21.400
really

00:47:21.400 --> 00:47:21.760
interested

00:47:21.760 --> 00:47:22.220
how

00:47:22.220 --> 00:47:22.700
PyPy

00:47:22.700 --> 00:47:23.440
compiles

00:47:23.440 --> 00:47:23.640
your

00:47:23.640 --> 00:47:23.920
program

00:47:23.920 --> 00:47:24.200
you can

00:47:24.200 --> 00:47:24.400
look

00:47:24.400 --> 00:47:24.600
into

00:47:24.600 --> 00:47:24.880
that

00:47:24.880 --> 00:47:25.720
so

00:47:25.720 --> 00:47:26.020
one

00:47:26.020 --> 00:47:26.460
related

00:47:26.460 --> 00:47:26.900
project

00:47:26.900 --> 00:47:27.260
that

00:47:27.260 --> 00:47:27.580
I've

00:47:27.580 --> 00:47:27.720
been

00:47:27.720 --> 00:47:28.000
working

00:47:28.000 --> 00:47:28.200
on

00:47:28.200 --> 00:47:28.580
recently

00:47:28.580 --> 00:47:28.860
quite

00:47:28.860 --> 00:47:29.160
a lot

00:47:29.160 --> 00:47:29.540
is

00:47:29.540 --> 00:47:30.180
called

00:47:30.180 --> 00:47:30.880
VMProf

00:47:30.880 --> 00:47:31.300
and

00:47:31.300 --> 00:47:31.980
VMProf

00:47:31.980 --> 00:47:32.420
is

00:47:32.420 --> 00:47:32.900
a

00:47:32.900 --> 00:47:34.140
low

00:47:34.140 --> 00:47:34.720
overhead

00:47:34.720 --> 00:47:35.360
statistical

00:47:35.360 --> 00:47:36.000
profiler

00:47:36.000 --> 00:47:36.480
for

00:47:36.480 --> 00:47:36.920
Python

00:47:36.920 --> 00:47:37.480
or

00:47:37.480 --> 00:47:37.700
for

00:47:37.700 --> 00:47:38.200
VMs

00:47:38.200 --> 00:47:38.340
in

00:47:38.340 --> 00:47:38.600
general

00:47:38.600 --> 00:47:38.800
but

00:47:38.800 --> 00:47:39.040
we're

00:47:39.040 --> 00:47:39.080
going

00:47:39.080 --> 00:47:39.200
to

00:47:39.200 --> 00:47:39.440
start

00:47:39.440 --> 00:47:39.680
with

00:47:39.680 --> 00:47:40.280
CPython

00:47:40.280 --> 00:47:40.480
and

00:47:40.480 --> 00:47:40.940
PyPy

00:47:40.940 --> 00:47:42.140
so

00:47:42.140 --> 00:47:42.600
those

00:47:42.600 --> 00:47:42.780
are

00:47:42.780 --> 00:47:43.220
tools

00:47:43.220 --> 00:47:43.460
that

00:47:43.460 --> 00:47:43.740
help

00:47:43.740 --> 00:47:44.320
developers

00:47:44.320 --> 00:47:44.940
find

00:47:44.940 --> 00:47:45.460
their

00:47:45.460 --> 00:47:46.280
bottlenecks

00:47:46.280 --> 00:47:46.580
in the

00:47:46.580 --> 00:47:46.900
code

00:47:46.900 --> 00:47:47.300
and

00:47:47.300 --> 00:47:48.260
find

00:47:48.260 --> 00:47:48.760
how

00:47:48.760 --> 00:47:49.460
to

00:47:49.460 --> 00:47:49.740
improve

00:47:49.740 --> 00:47:50.280
performance

00:47:50.280 --> 00:47:50.600
usually

00:47:50.600 --> 00:47:50.940
because

00:47:50.940 --> 00:47:51.140
if you

00:47:51.140 --> 00:47:51.260
can

00:47:51.260 --> 00:47:51.700
understand

00:47:51.700 --> 00:47:51.900
it

00:47:51.900 --> 00:47:52.020
you

00:47:52.020 --> 00:47:52.160
can

00:47:52.160 --> 00:47:52.480
usually

00:47:52.480 --> 00:47:52.900
improve

00:47:52.900 --> 00:47:53.160
it

00:47:53.160 --> 00:47:54.080
yeah

00:47:54.080 --> 00:47:54.340
that's

00:47:54.340 --> 00:47:54.640
excellent

00:47:54.640 --> 00:47:55.500
yeah

00:47:55.500 --> 00:47:56.060
we've

00:47:56.060 --> 00:47:56.160
been

00:47:56.160 --> 00:47:56.380
talking

00:47:56.380 --> 00:47:56.640
a lot

00:47:56.640 --> 00:47:56.820
about

00:47:56.820 --> 00:47:57.020
how

00:47:57.020 --> 00:47:57.380
PyPy

00:47:57.380 --> 00:47:57.680
makes

00:47:57.680 --> 00:47:57.900
stuff

00:47:57.900 --> 00:47:58.380
faster

00:47:58.380 --> 00:47:59.600
but

00:47:59.600 --> 00:47:59.920
before

00:47:59.920 --> 00:48:00.120
you

00:48:00.120 --> 00:48:00.300
just

00:48:00.300 --> 00:48:00.500
say

00:48:00.500 --> 00:48:00.800
well

00:48:00.800 --> 00:48:01.000
we're

00:48:01.000 --> 00:48:01.240
switching

00:48:01.240 --> 00:48:01.400
to

00:48:01.400 --> 00:48:01.580
some

00:48:01.580 --> 00:48:01.780
new

00:48:01.780 --> 00:48:02.320
interpreter

00:48:02.320 --> 00:48:02.840
maybe

00:48:02.840 --> 00:48:03.120
it

00:48:03.120 --> 00:48:03.300
makes

00:48:03.300 --> 00:48:03.480
sense

00:48:03.480 --> 00:48:03.620
to

00:48:03.620 --> 00:48:03.820
think

00:48:03.820 --> 00:48:04.020
about

00:48:04.020 --> 00:48:04.200
your

00:48:04.200 --> 00:48:04.620
algorithms

00:48:04.620 --> 00:48:04.860
and

00:48:04.860 --> 00:48:05.020
where

00:48:05.020 --> 00:48:05.200
they're

00:48:05.200 --> 00:48:05.520
slow

00:48:05.520 --> 00:48:05.700
and

00:48:05.700 --> 00:48:05.920
whether

00:48:05.920 --> 00:48:06.200
or not

00:48:06.200 --> 00:48:06.400
that

00:48:06.400 --> 00:48:06.660
switch

00:48:06.660 --> 00:48:06.800
would

00:48:06.800 --> 00:48:07.040
even

00:48:07.040 --> 00:48:07.400
help

00:48:07.400 --> 00:48:08.240
it

00:48:08.240 --> 00:48:08.820
it

00:48:08.820 --> 00:48:09.600
really

00:48:09.600 --> 00:48:09.980
depends

00:48:09.980 --> 00:48:10.120
on

00:48:10.120 --> 00:48:10.220
the

00:48:10.220 --> 00:48:10.580
situation

00:48:10.580 --> 00:48:11.000
sometimes

00:48:11.000 --> 00:48:11.280
you

00:48:11.280 --> 00:48:11.580
switch

00:48:11.580 --> 00:48:11.840
without

00:48:11.840 --> 00:48:12.260
thinking

00:48:12.260 --> 00:48:12.520
about

00:48:12.520 --> 00:48:12.680
it

00:48:12.680 --> 00:48:12.840
and

00:48:12.840 --> 00:48:13.260
sometimes

00:48:13.260 --> 00:48:13.500
it

00:48:13.500 --> 00:48:13.680
doesn't

00:48:13.680 --> 00:48:13.860
make

00:48:13.860 --> 00:48:14.100
sense

00:48:14.100 --> 00:48:14.240
and

00:48:14.240 --> 00:48:14.340
you

00:48:14.340 --> 00:48:14.500
have

00:48:14.500 --> 00:48:14.620
to

00:48:14.620 --> 00:48:14.780
think

00:48:14.780 --> 00:48:15.000
about

00:48:15.000 --> 00:48:15.160
it

00:48:15.160 --> 00:48:15.440
first

00:48:15.440 --> 00:48:15.840
it

00:48:15.840 --> 00:48:16.260
really

00:48:16.260 --> 00:48:16.840
depends

00:48:16.840 --> 00:48:17.000
on

00:48:17.000 --> 00:48:17.100
your

00:48:17.100 --> 00:48:17.440
program

00:48:17.440 --> 00:48:17.640
and

00:48:17.640 --> 00:48:17.840
what

00:48:17.840 --> 00:48:18.060
are

00:48:18.060 --> 00:48:18.180
you

00:48:18.180 --> 00:48:18.840
trying

00:48:18.840 --> 00:48:19.020
to

00:48:19.020 --> 00:48:19.320
achieve

00:48:19.320 --> 00:48:19.800
and

00:48:19.800 --> 00:48:20.100
sometimes

00:48:20.100 --> 00:48:20.300
you

00:48:20.300 --> 00:48:20.420
want

00:48:20.420 --> 00:48:20.540
to

00:48:20.540 --> 00:48:20.880
switch

00:48:20.880 --> 00:48:21.400
look

00:48:21.400 --> 00:48:21.880
improve

00:48:21.880 --> 00:48:22.220
sometimes

00:48:22.220 --> 00:48:22.480
you

00:48:22.480 --> 00:48:22.660
want

00:48:22.660 --> 00:48:22.760
to

00:48:22.760 --> 00:48:22.900
do

00:48:22.900 --> 00:48:23.280
both

00:48:23.280 --> 00:48:23.900
yeah

00:48:23.900 --> 00:48:24.180
well

00:48:24.180 --> 00:48:24.560
at

00:48:24.560 --> 00:48:25.160
minimum

00:48:25.160 --> 00:48:25.360
you

00:48:25.360 --> 00:48:25.620
probably

00:48:25.620 --> 00:48:25.880
want

00:48:25.880 --> 00:48:26.040
to

00:48:26.040 --> 00:48:26.660
measure

00:48:26.660 --> 00:48:27.000
and

00:48:27.000 --> 00:48:27.400
profile

00:48:27.400 --> 00:48:27.640
your

00:48:27.640 --> 00:48:27.900
app

00:48:27.900 --> 00:48:28.280
and

00:48:28.280 --> 00:48:28.740
try

00:48:28.740 --> 00:48:28.880
it

00:48:28.880 --> 00:48:29.100
on

00:48:29.100 --> 00:48:34.360
you

00:48:34.360 --> 00:48:34.700
definitely

00:48:34.700 --> 00:48:34.900
want

00:48:34.900 --> 00:48:35.000
to

00:48:35.000 --> 00:48:35.200
measure

00:48:35.200 --> 00:48:35.420
you

00:48:35.420 --> 00:48:35.720
definitely

00:48:35.720 --> 00:48:35.980
want

00:48:35.980 --> 00:48:36.080
to

00:48:36.080 --> 00:48:36.240
know

00:48:36.240 --> 00:48:36.520
how

00:48:36.520 --> 00:48:36.840
fast

00:48:36.840 --> 00:48:37.000
your

00:48:37.000 --> 00:48:37.400
application

00:48:37.400 --> 00:48:37.600
is

00:48:37.600 --> 00:48:38.380
running

00:48:38.380 --> 00:48:38.800
before

00:48:38.800 --> 00:48:39.740
attempting

00:48:39.740 --> 00:48:40.240
anything

00:48:40.240 --> 00:48:40.680
it

00:48:40.680 --> 00:48:40.940
felt

00:48:40.940 --> 00:48:41.260
a little

00:48:41.260 --> 00:48:41.660
faster

00:48:41.660 --> 00:48:42.000
let's

00:48:42.000 --> 00:48:42.160
do

00:48:42.160 --> 00:48:43.280
it

00:48:43.280 --> 00:48:44.020
exactly

00:48:44.020 --> 00:48:45.140
you're

00:48:45.140 --> 00:48:45.420
laughing

00:48:45.420 --> 00:48:45.720
but

00:48:45.720 --> 00:48:46.040
we've

00:48:46.040 --> 00:48:46.180
seen

00:48:46.180 --> 00:48:46.460
people

00:48:46.460 --> 00:48:46.720
like

00:48:46.720 --> 00:48:47.020
that

00:48:47.020 --> 00:48:47.460
like

00:48:47.460 --> 00:48:48.040
my

00:48:48.040 --> 00:48:48.520
application

00:48:48.520 --> 00:48:48.980
runs

00:48:48.980 --> 00:48:49.520
faster

00:48:49.520 --> 00:48:49.940
on

00:48:49.940 --> 00:48:50.900
my

00:48:50.900 --> 00:48:51.200
local

00:48:51.200 --> 00:48:51.520
machine

00:48:51.520 --> 00:48:51.700
but

00:48:51.700 --> 00:48:51.900
not

00:48:51.900 --> 00:48:52.060
on

00:48:52.060 --> 00:48:52.200
the

00:48:52.200 --> 00:48:52.500
server

00:48:52.500 --> 00:48:53.100
okay

00:48:53.100 --> 00:48:54.140
how

00:48:54.140 --> 00:48:54.340
did

00:48:54.340 --> 00:48:54.440
you

00:48:54.440 --> 00:48:54.760
benchmark

00:48:54.760 --> 00:48:55.240
oh

00:48:55.240 --> 00:48:55.380
I

00:48:55.380 --> 00:48:55.640
looked

00:48:55.640 --> 00:48:55.760
at

00:48:55.760 --> 00:48:55.900
the

00:48:55.900 --> 00:48:56.200
loading

00:48:56.200 --> 00:48:56.520
time

00:48:56.520 --> 00:48:57.000
Chrome

00:48:57.000 --> 00:48:57.780
like

00:48:57.780 --> 00:48:58.300
developer

00:48:58.300 --> 00:48:58.760
tools

00:48:58.760 --> 00:48:59.940
that's

00:48:59.940 --> 00:49:00.340
not

00:49:00.340 --> 00:49:00.680
good

00:49:00.680 --> 00:49:01.040
enough

00:49:01.040 --> 00:49:01.620
usually

00:49:01.620 --> 00:49:02.140
that's

00:49:02.140 --> 00:49:02.500
like

00:49:02.500 --> 00:49:04.980
yes

00:49:04.980 --> 00:49:05.360
it might

00:49:05.360 --> 00:49:05.520
be

00:49:05.520 --> 00:49:05.840
slower

00:49:05.840 --> 00:49:06.120
because

00:49:06.120 --> 00:49:06.280
your

00:49:06.280 --> 00:49:06.620
network

00:49:06.620 --> 00:49:06.860
is

00:49:06.860 --> 00:49:07.260
slower

00:49:07.260 --> 00:49:07.640
I

00:49:07.640 --> 00:49:07.940
don't

00:49:07.940 --> 00:49:08.160
know

00:49:08.160 --> 00:49:08.320
what

00:49:08.320 --> 00:49:08.480
your

00:49:08.480 --> 00:49:08.760
setup

00:49:08.760 --> 00:49:09.140
is

00:49:09.140 --> 00:49:09.540
maybe

00:49:09.540 --> 00:49:10.080
the

00:49:10.080 --> 00:49:10.320
ping

00:49:10.320 --> 00:49:10.560
time

00:49:10.560 --> 00:49:10.680
is

00:49:10.680 --> 00:49:10.960
100

00:49:10.960 --> 00:49:11.460
milliseconds

00:49:11.460 --> 00:49:11.700
the

00:49:11.700 --> 00:49:11.980
request

00:49:11.980 --> 00:49:12.180
time

00:49:12.180 --> 00:49:12.320
is

00:49:12.320 --> 00:49:12.580
10

00:49:12.580 --> 00:49:13.020
milliseconds

00:49:13.020 --> 00:49:13.420
so

00:49:13.420 --> 00:49:13.780
geez

00:49:13.780 --> 00:49:13.940
it's

00:49:13.940 --> 00:49:14.080
really

00:49:14.080 --> 00:49:14.340
slow

00:49:14.340 --> 00:49:14.600
on the

00:49:14.600 --> 00:49:14.860
server

00:49:14.860 --> 00:49:15.240
right

00:49:15.240 --> 00:49:16.800
awesome

00:49:16.800 --> 00:49:18.040
all right

00:49:18.040 --> 00:49:18.820
Manja

00:49:18.820 --> 00:49:19.520
this is

00:49:19.520 --> 00:49:19.760
probably

00:49:19.760 --> 00:49:20.020
a good

00:49:20.020 --> 00:49:20.220
place

00:49:20.220 --> 00:49:20.520
to wrap

00:49:20.520 --> 00:49:20.640
up

00:49:20.640 --> 00:49:20.780
the

00:49:20.780 --> 00:49:20.920
show

00:49:20.920 --> 00:49:21.100
this

00:49:21.100 --> 00:49:21.200
has

00:49:21.200 --> 00:49:21.320
been

00:49:21.320 --> 00:49:21.760
such

00:49:21.760 --> 00:49:21.960
an

00:49:21.960 --> 00:49:22.340
interesting

00:49:22.340 --> 00:49:22.960
conversation

00:49:22.960 --> 00:49:23.560
I'm

00:49:23.560 --> 00:49:24.000
really

00:49:24.000 --> 00:49:24.380
excited

00:49:24.380 --> 00:49:24.560
about

00:49:24.560 --> 00:49:24.700
what

00:49:24.700 --> 00:49:24.800
you

00:49:24.800 --> 00:49:25.020
are

00:49:25.020 --> 00:49:25.220
doing

00:49:25.220 --> 00:49:25.420
and

00:49:25.420 --> 00:49:25.840
you

00:49:25.840 --> 00:49:25.920
know

00:49:25.920 --> 00:49:26.020
I

00:49:26.020 --> 00:49:26.180
hope

00:49:26.180 --> 00:49:26.300
you

00:49:26.300 --> 00:49:26.460
keep

00:49:26.460 --> 00:49:26.740
going

00:49:26.740 --> 00:49:27.800
I

00:49:27.800 --> 00:49:27.980
want

00:49:27.980 --> 00:49:28.040
to

00:49:28.040 --> 00:49:28.180
make

00:49:28.180 --> 00:49:28.340
sure

00:49:28.340 --> 00:49:28.480
that

00:49:28.480 --> 00:49:28.640
people

00:49:28.640 --> 00:49:28.880
know

00:49:28.880 --> 00:49:29.200
that

00:49:29.200 --> 00:49:29.500
the

00:49:29.500 --> 00:49:29.740
source

00:49:29.740 --> 00:49:29.960
code

00:49:29.960 --> 00:49:30.100
is

00:49:30.100 --> 00:49:30.300
on

00:49:30.300 --> 00:49:30.920
bitbucket

00:49:30.920 --> 00:49:31.160
they can

00:49:31.160 --> 00:49:31.380
go to

00:49:31.380 --> 00:49:32.080
bitbucket.org

00:49:32.080 --> 00:49:32.320
slash

00:49:32.320 --> 00:49:32.660
pipi

00:49:32.660 --> 00:49:33.120
that's the

00:49:33.120 --> 00:49:33.720
main repo

00:49:33.720 --> 00:49:36.100
the main

00:49:36.100 --> 00:49:36.540
way to

00:49:36.540 --> 00:49:37.160
contact us

00:49:37.160 --> 00:49:37.620
is usually

00:49:37.620 --> 00:49:37.960
through

00:49:37.960 --> 00:49:38.300
either

00:49:38.300 --> 00:49:38.660
mailing

00:49:38.660 --> 00:49:38.980
list

00:49:38.980 --> 00:49:39.200
or

00:49:39.200 --> 00:49:39.720
irc

00:49:39.720 --> 00:49:40.140
we

00:49:40.140 --> 00:49:40.960
hang

00:49:40.960 --> 00:49:41.140
out

00:49:41.140 --> 00:49:41.260
on

00:49:41.260 --> 00:49:41.600
irc

00:49:41.600 --> 00:49:41.940
a lot

00:49:41.940 --> 00:49:42.180
it's

00:49:42.180 --> 00:49:42.380
hash

00:49:42.380 --> 00:49:42.780
pipi

00:49:42.780 --> 00:49:42.940
on

00:49:42.940 --> 00:49:43.200
free

00:49:43.200 --> 00:49:43.540
node

00:49:43.540 --> 00:49:43.940
and

00:49:43.940 --> 00:49:45.280
we're

00:49:45.280 --> 00:49:45.560
usually

00:49:45.560 --> 00:49:45.840
quite

00:49:45.840 --> 00:49:46.400
approachable

00:49:46.400 --> 00:49:46.820
when you

00:49:46.820 --> 00:49:47.280
come

00:49:47.280 --> 00:49:48.000
with

00:49:48.000 --> 00:49:48.440
problems

00:49:48.440 --> 00:49:48.880
and

00:49:48.880 --> 00:49:49.280
one

00:49:49.280 --> 00:49:49.720
interesting

00:49:49.720 --> 00:49:50.040
thing

00:49:50.040 --> 00:49:50.280
is

00:49:50.280 --> 00:49:50.820
if

00:49:50.820 --> 00:49:50.920
you

00:49:50.920 --> 00:49:51.160
find

00:49:51.160 --> 00:49:51.320
your

00:49:51.320 --> 00:49:51.760
program

00:49:51.760 --> 00:49:52.660
running

00:49:52.660 --> 00:49:53.180
slower

00:49:53.180 --> 00:49:53.500
on their

00:49:53.500 --> 00:49:53.980
pipi

00:49:53.980 --> 00:49:54.360
than

00:49:54.360 --> 00:49:54.580
c

00:49:54.580 --> 00:49:54.840
python

00:49:54.840 --> 00:49:55.260
it's

00:49:55.260 --> 00:49:55.580
usually

00:49:55.580 --> 00:49:56.020
considered

00:49:56.020 --> 00:49:56.460
a bug

00:49:56.460 --> 00:49:56.780
unless

00:49:56.780 --> 00:49:57.020
you're

00:49:57.020 --> 00:49:57.220
using

00:49:57.220 --> 00:49:57.500
a lot

00:49:57.500 --> 00:49:57.640
of

00:49:57.640 --> 00:49:57.800
c

00:49:57.800 --> 00:49:58.420
extensions

00:49:58.420 --> 00:49:59.080
right

00:49:59.080 --> 00:49:59.280
so

00:49:59.280 --> 00:49:59.500
if

00:49:59.500 --> 00:49:59.700
people

00:49:59.700 --> 00:49:59.880
run

00:49:59.880 --> 00:50:00.020
into

00:50:00.020 --> 00:50:00.140
that

00:50:00.140 --> 00:50:00.340
maybe

00:50:00.340 --> 00:50:00.500
they

00:50:00.500 --> 00:50:00.720
should

00:50:00.720 --> 00:50:01.560
communicate

00:50:01.560 --> 00:50:01.780
with

00:50:01.780 --> 00:50:01.900
you

00:50:01.900 --> 00:50:02.140
guys

00:50:02.140 --> 00:50:02.340
and

00:50:02.340 --> 00:50:03.320
they

00:50:03.320 --> 00:50:03.480
can

00:50:03.480 --> 00:50:03.740
definitely

00:50:03.740 --> 00:50:04.140
file a

00:50:04.140 --> 00:50:04.400
bug

00:50:04.400 --> 00:50:04.720
and

00:50:04.720 --> 00:50:06.020
complain

00:50:06.020 --> 00:50:06.780
excellent

00:50:06.780 --> 00:50:07.360
two

00:50:07.360 --> 00:50:07.600
quick

00:50:07.600 --> 00:50:07.980
questions

00:50:07.980 --> 00:50:08.160
I

00:50:08.160 --> 00:50:08.480
typically

00:50:08.480 --> 00:50:08.760
ask

00:50:08.760 --> 00:50:09.020
people

00:50:09.020 --> 00:50:09.140
at

00:50:09.140 --> 00:50:09.180
the

00:50:09.180 --> 00:50:09.260
end

00:50:09.260 --> 00:50:09.360
of

00:50:09.360 --> 00:50:09.440
the

00:50:09.440 --> 00:50:09.620
show

00:50:09.620 --> 00:50:10.060
what

00:50:10.060 --> 00:50:10.660
what's

00:50:10.660 --> 00:50:10.740
your

00:50:10.740 --> 00:50:11.000
favorite

00:50:11.000 --> 00:50:11.320
editor

00:50:11.320 --> 00:50:11.740
how do

00:50:11.740 --> 00:50:11.780
you

00:50:11.780 --> 00:50:11.940
write

00:50:11.940 --> 00:50:12.220
code

00:50:12.220 --> 00:50:12.440
during

00:50:12.440 --> 00:50:12.560
the

00:50:12.560 --> 00:50:12.760
day

00:50:12.760 --> 00:50:13.500
I

00:50:13.500 --> 00:50:13.780
have

00:50:13.780 --> 00:50:14.280
heavily

00:50:14.280 --> 00:50:14.680
hacked

00:50:14.680 --> 00:50:15.200
emux

00:50:15.200 --> 00:50:15.840
actually

00:50:15.840 --> 00:50:16.400
that

00:50:16.400 --> 00:50:17.380
does

00:50:17.380 --> 00:50:17.700
all

00:50:17.700 --> 00:50:17.980
kinds

00:50:17.980 --> 00:50:18.120
of

00:50:18.120 --> 00:50:18.400
weird

00:50:18.400 --> 00:50:18.880
stuff

00:50:18.880 --> 00:50:19.360
and

00:50:19.360 --> 00:50:20.180
I'm

00:50:20.180 --> 00:50:20.400
way

00:50:20.400 --> 00:50:20.660
more

00:50:20.660 --> 00:50:21.120
proficient

00:50:21.120 --> 00:50:21.460
with

00:50:21.460 --> 00:50:22.340
elisp

00:50:22.340 --> 00:50:22.580
than

00:50:22.580 --> 00:50:22.720
I

00:50:22.720 --> 00:50:22.860
would

00:50:22.860 --> 00:50:23.120
ever

00:50:23.120 --> 00:50:23.460
want

00:50:23.460 --> 00:50:23.620
to

00:50:23.620 --> 00:50:23.920
be

00:50:23.920 --> 00:50:24.540
actually

00:50:24.540 --> 00:50:25.820
a

00:50:25.820 --> 00:50:26.080
skill

00:50:26.080 --> 00:50:26.220
you

00:50:26.220 --> 00:50:26.380
didn't

00:50:26.380 --> 00:50:26.580
really

00:50:26.580 --> 00:50:26.860
want

00:50:26.860 --> 00:50:27.020
to

00:50:27.020 --> 00:50:27.360
earn

00:50:27.360 --> 00:50:27.580
but

00:50:27.580 --> 00:50:27.760
you

00:50:27.760 --> 00:50:28.000
you've

00:50:28.000 --> 00:50:28.140
done

00:50:28.140 --> 00:50:28.280
it

00:50:28.280 --> 00:50:28.520
anyway

00:50:28.520 --> 00:50:28.840
huh

00:50:28.840 --> 00:50:30.240
something

00:50:30.240 --> 00:50:30.580
like

00:50:30.580 --> 00:50:30.760
that

00:50:30.760 --> 00:50:30.980
yeah

00:50:30.980 --> 00:50:31.440
and

00:50:31.440 --> 00:50:31.600
then

00:50:31.600 --> 00:50:31.940
also

00:50:31.940 --> 00:50:32.420
what's

00:50:32.420 --> 00:50:33.420
a

00:50:33.420 --> 00:50:34.140
notable

00:50:34.140 --> 00:50:34.900
or

00:50:34.900 --> 00:50:35.560
interesting

00:50:35.560 --> 00:50:36.640
pypi

00:50:36.640 --> 00:50:37.140
package

00:50:37.140 --> 00:50:38.200
that

00:50:38.200 --> 00:50:38.540
you

00:50:38.540 --> 00:50:39.200
want

00:50:39.200 --> 00:50:39.280
to

00:50:39.280 --> 00:50:39.380
tell

00:50:39.380 --> 00:50:39.580
people

00:50:39.580 --> 00:50:39.840
about

00:50:39.840 --> 00:50:40.380
that's

00:50:40.380 --> 00:50:40.500
a

00:50:40.500 --> 00:50:40.720
tough

00:50:40.720 --> 00:50:40.900
one

00:50:40.900 --> 00:50:41.100
for

00:50:41.100 --> 00:50:41.300
me

00:50:41.300 --> 00:50:41.560
because

00:50:41.560 --> 00:50:41.780
I

00:50:41.780 --> 00:50:42.060
don't

00:50:42.060 --> 00:50:42.460
actually

00:50:42.460 --> 00:50:42.760
write

00:50:42.760 --> 00:50:43.100
all that

00:50:43.100 --> 00:50:43.300
much

00:50:43.300 --> 00:50:43.680
Python

00:50:43.680 --> 00:50:44.100
code

00:50:44.100 --> 00:50:44.500
that's

00:50:44.500 --> 00:50:44.860
using

00:50:44.860 --> 00:50:45.360
libraries

00:50:45.360 --> 00:50:46.140
you can't

00:50:46.140 --> 00:50:46.380
import

00:50:46.380 --> 00:50:46.840
too much

00:50:46.840 --> 00:50:47.300
into the

00:50:47.300 --> 00:50:47.460
like

00:50:47.460 --> 00:50:47.640
the

00:50:47.640 --> 00:50:47.980
core

00:50:47.980 --> 00:50:48.740
core

00:50:48.740 --> 00:50:49.060
bits

00:50:49.060 --> 00:50:49.360
right

00:50:49.360 --> 00:50:50.380
right

00:50:50.380 --> 00:50:50.580
but

00:50:50.580 --> 00:50:50.980
definitely

00:50:50.980 --> 00:50:52.080
and I

00:50:52.080 --> 00:50:52.220
mean

00:50:52.220 --> 00:50:52.620
it is

00:50:52.620 --> 00:50:52.840
self

00:50:52.840 --> 00:50:53.300
promotion

00:50:53.300 --> 00:50:53.700
but

00:50:53.700 --> 00:50:54.100
definitely

00:50:54.100 --> 00:50:54.820
cffi

00:50:54.820 --> 00:50:55.040
is

00:50:55.040 --> 00:50:55.340
something

00:50:55.340 --> 00:50:55.600
that

00:50:55.600 --> 00:50:55.700
I

00:50:55.700 --> 00:50:55.840
would

00:50:55.840 --> 00:50:56.180
recommend

00:50:56.180 --> 00:50:56.600
people

00:50:56.600 --> 00:50:56.860
to

00:50:56.860 --> 00:50:57.100
look

00:50:57.100 --> 00:50:57.260
at

00:50:57.260 --> 00:50:57.480
as

00:50:57.480 --> 00:50:57.580
a

00:50:57.580 --> 00:50:57.720
way

00:50:57.720 --> 00:50:57.900
to

00:50:57.900 --> 00:50:58.080
call

00:50:58.080 --> 00:50:58.320
c

00:50:58.320 --> 00:50:58.780
because

00:50:58.780 --> 00:50:59.040
this

00:50:59.040 --> 00:50:59.200
is

00:50:59.200 --> 00:50:59.540
something

00:50:59.540 --> 00:50:59.860
very

00:50:59.860 --> 00:51:00.260
low

00:51:00.260 --> 00:51:00.880
that

00:51:00.880 --> 00:51:02.280
has

00:51:02.280 --> 00:51:02.520
been

00:51:02.520 --> 00:51:02.880
very

00:51:02.880 --> 00:51:03.420
successful

00:51:03.420 --> 00:51:04.380
as a

00:51:04.380 --> 00:51:04.740
simple

00:51:04.740 --> 00:51:05.140
simple

00:51:05.140 --> 00:51:05.480
simple

00:51:05.480 --> 00:51:05.860
way

00:51:05.860 --> 00:51:06.040
to

00:51:06.040 --> 00:51:06.220
call

00:51:06.220 --> 00:51:06.480
c

00:51:06.480 --> 00:51:06.980
that's

00:51:06.980 --> 00:51:07.180
cool

00:51:07.180 --> 00:51:07.400
and

00:51:07.400 --> 00:51:07.620
if

00:51:07.620 --> 00:51:07.740
I

00:51:07.740 --> 00:51:07.900
was

00:51:07.900 --> 00:51:08.140
writing

00:51:08.140 --> 00:51:08.380
some

00:51:08.380 --> 00:51:08.840
program

00:51:08.840 --> 00:51:09.620
in

00:51:09.620 --> 00:51:09.940
Python

00:51:09.940 --> 00:51:10.260
and

00:51:10.260 --> 00:51:10.400
I

00:51:10.400 --> 00:51:10.640
had

00:51:10.640 --> 00:51:11.060
some

00:51:11.060 --> 00:51:12.280
computational

00:51:12.280 --> 00:51:12.720
bits

00:51:12.720 --> 00:51:12.900
I'd

00:51:12.900 --> 00:51:13.100
written

00:51:13.100 --> 00:51:13.260
in

00:51:13.260 --> 00:51:13.440
c

00:51:13.440 --> 00:51:13.600
I

00:51:13.600 --> 00:51:13.740
could

00:51:13.740 --> 00:51:14.000
wire

00:51:14.000 --> 00:51:14.180
them

00:51:14.180 --> 00:51:14.500
together

00:51:14.500 --> 00:51:14.720
with

00:51:14.720 --> 00:51:15.660
cffi

00:51:15.660 --> 00:51:17.000
you'll

00:51:17.000 --> 00:51:17.120
be

00:51:17.120 --> 00:51:17.500
surprised

00:51:17.500 --> 00:51:17.700
how

00:51:17.700 --> 00:51:17.960
few

00:51:17.960 --> 00:51:18.200
people

00:51:18.200 --> 00:51:18.680
actually

00:51:18.680 --> 00:51:18.940
do

00:51:18.940 --> 00:51:19.200
that

00:51:19.200 --> 00:51:19.820
most

00:51:19.820 --> 00:51:19.980
of

00:51:19.980 --> 00:51:20.080
the

00:51:20.080 --> 00:51:20.280
time

00:51:20.280 --> 00:51:20.820
I

00:51:20.820 --> 00:51:21.080
have

00:51:21.080 --> 00:51:21.240
this

00:51:21.240 --> 00:51:21.500
Python

00:51:21.500 --> 00:51:21.840
program

00:51:21.840 --> 00:51:22.160
and I

00:51:22.160 --> 00:51:22.300
have

00:51:22.300 --> 00:51:22.480
this

00:51:22.480 --> 00:51:22.840
obscure

00:51:22.840 --> 00:51:23.120
c

00:51:23.120 --> 00:51:23.480
library

00:51:23.480 --> 00:51:23.740
that

00:51:23.740 --> 00:51:24.320
accesses

00:51:24.320 --> 00:51:24.560
this

00:51:24.560 --> 00:51:25.340
weird

00:51:25.340 --> 00:51:25.780
device

00:51:25.780 --> 00:51:25.980
that

00:51:25.980 --> 00:51:26.340
nobody

00:51:26.340 --> 00:51:26.600
heard

00:51:26.600 --> 00:51:26.960
about

00:51:26.960 --> 00:51:28.020
and

00:51:28.020 --> 00:51:28.180
I

00:51:28.180 --> 00:51:28.400
need

00:51:28.400 --> 00:51:28.580
to

00:51:28.580 --> 00:51:28.780
call

00:51:28.780 --> 00:51:28.920
it

00:51:28.920 --> 00:51:29.240
somehow

00:51:29.240 --> 00:51:29.460
and

00:51:29.460 --> 00:51:29.720
that's

00:51:29.720 --> 00:51:29.900
why

00:51:29.900 --> 00:51:30.100
you

00:51:30.100 --> 00:51:30.280
call

00:51:30.280 --> 00:51:30.480
c

00:51:30.480 --> 00:51:31.060
the

00:51:31.060 --> 00:51:31.960
computational

00:51:31.960 --> 00:51:32.520
bits

00:51:32.520 --> 00:51:33.480
it's

00:51:33.480 --> 00:51:33.940
actually

00:51:33.940 --> 00:51:34.280
quite

00:51:34.280 --> 00:51:34.640
rare

00:51:34.640 --> 00:51:34.880
but

00:51:34.880 --> 00:51:35.120
that

00:51:35.120 --> 00:51:35.500
would

00:51:35.500 --> 00:51:35.660
be

00:51:35.660 --> 00:51:35.800
an

00:51:35.800 --> 00:51:36.040
option

00:51:36.040 --> 00:51:36.320
too

00:51:36.320 --> 00:51:36.640
yeah

00:51:36.640 --> 00:51:36.940
sure

00:51:36.940 --> 00:51:37.340
sure

00:51:37.340 --> 00:51:38.160
okay

00:51:38.160 --> 00:51:39.080
awesome

00:51:39.080 --> 00:51:39.560
and

00:51:39.560 --> 00:51:39.820
then

00:51:39.820 --> 00:51:40.440
finally

00:51:40.440 --> 00:51:40.760
just

00:51:40.760 --> 00:51:41.880
you said

00:51:41.880 --> 00:51:42.060
that you

00:51:42.060 --> 00:51:42.180
do

00:51:42.180 --> 00:51:42.340
some

00:51:42.340 --> 00:51:42.760
consulting

00:51:42.760 --> 00:51:43.400
do you

00:51:43.400 --> 00:51:43.660
want to

00:51:43.660 --> 00:51:43.920
maybe

00:51:43.920 --> 00:51:44.240
talk

00:51:44.240 --> 00:51:44.540
a little

00:51:44.540 --> 00:51:44.700
bit

00:51:44.700 --> 00:51:44.880
about

00:51:44.880 --> 00:51:45.000
what

00:51:45.000 --> 00:51:45.120
you

00:51:45.120 --> 00:51:45.280
do

00:51:45.280 --> 00:51:45.500
so

00:51:45.500 --> 00:51:45.680
if

00:51:45.680 --> 00:51:45.900
people

00:51:45.900 --> 00:51:46.060
want

00:51:46.060 --> 00:51:46.140
to

00:51:46.140 --> 00:51:46.400
contact

00:51:46.400 --> 00:51:46.700
you

00:51:46.700 --> 00:51:46.920
or

00:51:46.920 --> 00:51:47.140
anything

00:51:47.140 --> 00:51:47.380
like

00:51:47.380 --> 00:51:47.700
that

00:51:47.700 --> 00:51:48.240
so

00:51:48.240 --> 00:51:48.460
the

00:51:48.460 --> 00:51:48.920
website

00:51:48.920 --> 00:51:49.400
is

00:51:49.400 --> 00:51:50.700
barocksoftware.com

00:51:50.700 --> 00:51:51.020
and

00:51:51.020 --> 00:51:51.460
essentially

00:51:51.460 --> 00:51:52.240
what

00:51:52.240 --> 00:51:52.460
we

00:51:52.460 --> 00:51:52.800
do

00:51:52.800 --> 00:51:53.200
is

00:51:53.200 --> 00:51:53.620
we

00:51:53.620 --> 00:51:53.900
make

00:51:53.900 --> 00:51:54.100
your

00:51:54.100 --> 00:51:54.420
Python

00:51:54.420 --> 00:51:54.900
programs

00:51:54.900 --> 00:51:55.080
run

00:51:55.080 --> 00:51:55.480
faster

00:51:55.480 --> 00:51:55.840
like

00:51:55.840 --> 00:51:56.020
the

00:51:56.020 --> 00:51:56.220
same

00:51:56.220 --> 00:51:56.580
thing

00:51:56.580 --> 00:51:56.800
as

00:51:56.800 --> 00:51:56.960
we

00:51:56.960 --> 00:51:57.080
do

00:51:57.080 --> 00:51:57.200
in

00:51:57.200 --> 00:51:57.420
open

00:51:57.420 --> 00:51:57.720
source

00:51:57.720 --> 00:51:58.060
except

00:51:58.060 --> 00:51:58.360
on

00:51:58.360 --> 00:51:58.520
the

00:51:58.520 --> 00:51:58.900
commercial

00:51:58.900 --> 00:51:59.300
side

00:51:59.300 --> 00:51:59.880
so

00:51:59.880 --> 00:52:00.300
typically

00:52:00.300 --> 00:52:00.640
if

00:52:00.640 --> 00:52:00.900
your

00:52:00.900 --> 00:52:01.280
open

00:52:01.280 --> 00:52:01.520
source

00:52:01.520 --> 00:52:01.860
software

00:52:01.860 --> 00:52:02.020
is

00:52:02.020 --> 00:52:02.500
running

00:52:02.500 --> 00:52:02.740
too

00:52:02.740 --> 00:52:02.940
slow

00:52:02.940 --> 00:52:03.160
just

00:52:03.160 --> 00:52:03.340
come

00:52:03.340 --> 00:52:03.480
to

00:52:03.480 --> 00:52:03.920
IRC

00:52:03.920 --> 00:52:04.300
and

00:52:04.300 --> 00:52:04.440
if

00:52:04.440 --> 00:52:04.620
your

00:52:04.620 --> 00:52:05.320
commercial

00:52:05.320 --> 00:52:05.720
software

00:52:05.720 --> 00:52:05.880
is

00:52:05.880 --> 00:52:06.100
running

00:52:06.100 --> 00:52:06.320
too

00:52:06.320 --> 00:52:06.500
slow

00:52:06.500 --> 00:52:06.700
we

00:52:06.700 --> 00:52:06.980
can

00:52:06.980 --> 00:52:07.520
definitely

00:52:07.520 --> 00:52:08.420
do

00:52:08.420 --> 00:52:08.560
a

00:52:08.560 --> 00:52:08.960
contract

00:52:08.960 --> 00:52:09.180
with

00:52:09.180 --> 00:52:09.320
you

00:52:09.320 --> 00:52:09.460
to

00:52:09.460 --> 00:52:09.680
make

00:52:09.680 --> 00:52:09.880
it

00:52:09.880 --> 00:52:10.120
run

00:52:10.120 --> 00:52:10.520
faster

00:52:10.520 --> 00:52:11.180
yeah

00:52:11.180 --> 00:52:11.440
that's

00:52:11.440 --> 00:52:11.680
awesome

00:52:11.680 --> 00:52:12.040
yeah

00:52:12.040 --> 00:52:12.260
so

00:52:12.260 --> 00:52:12.540
I'm

00:52:12.540 --> 00:52:12.720
sure

00:52:12.720 --> 00:52:13.040
people

00:52:13.040 --> 00:52:13.240
who

00:52:13.240 --> 00:52:13.360
are

00:52:13.360 --> 00:52:13.560
having

00:52:13.560 --> 00:52:13.860
trouble

00:52:13.860 --> 00:52:14.160
might

00:52:14.160 --> 00:52:14.380
be

00:52:14.380 --> 00:52:14.820
interested

00:52:14.820 --> 00:52:15.040
in

00:52:15.040 --> 00:52:15.240
checking

00:52:15.240 --> 00:52:15.400
that

00:52:15.400 --> 00:52:15.580
out

00:52:15.580 --> 00:52:15.800
so

00:52:15.800 --> 00:52:16.080
great

00:52:16.080 --> 00:52:17.580
Machia

00:52:17.580 --> 00:52:17.840
this

00:52:17.840 --> 00:52:17.980
has

00:52:17.980 --> 00:52:18.100
been

00:52:18.100 --> 00:52:18.360
super

00:52:18.360 --> 00:52:18.660
fun

00:52:18.660 --> 00:52:18.980
I've

00:52:18.980 --> 00:52:19.140
learned

00:52:19.140 --> 00:52:19.440
a lot

00:52:19.440 --> 00:52:19.780
thanks

00:52:19.780 --> 00:52:21.200
thank you

00:52:21.200 --> 00:52:21.580
Michael

00:52:21.580 --> 00:52:22.160
have a good

00:52:22.160 --> 00:52:22.420
day

00:52:22.420 --> 00:52:22.620
yeah

00:52:22.620 --> 00:52:23.020
you too

00:52:23.020 --> 00:52:24.660
this

00:52:24.660 --> 00:52:24.940
has been

00:52:24.940 --> 00:52:25.180
another

00:52:25.180 --> 00:52:25.580
episode

00:52:25.580 --> 00:52:25.940
of

00:52:25.940 --> 00:52:26.320
talk

00:52:26.320 --> 00:52:26.780
Python

00:52:26.780 --> 00:52:26.980
to

00:52:26.980 --> 00:52:27.180
me

00:52:27.180 --> 00:52:27.820
today's

00:52:27.820 --> 00:52:28.020
guest

00:52:28.020 --> 00:52:28.220
was

00:52:28.220 --> 00:52:28.580
Machia

00:52:28.580 --> 00:52:29.160
Falkowski

00:52:29.160 --> 00:52:29.640
and this

00:52:29.640 --> 00:52:30.020
episode

00:52:30.020 --> 00:52:30.460
has been

00:52:30.460 --> 00:52:30.940
sponsored

00:52:30.940 --> 00:52:31.280
by

00:52:31.280 --> 00:52:31.760
Hired

00:52:31.760 --> 00:52:32.120
and

00:52:32.120 --> 00:52:32.740
Codeship

00:52:32.740 --> 00:52:33.460
thank

00:52:33.460 --> 00:52:33.820
you guys

00:52:33.820 --> 00:52:34.020
for

00:52:34.020 --> 00:52:34.360
supporting

00:52:34.360 --> 00:52:34.580
the

00:52:34.580 --> 00:52:34.860
show

00:52:34.860 --> 00:52:36.180
Hired

00:52:36.180 --> 00:52:36.440
wants

00:52:36.440 --> 00:52:36.760
to help

00:52:36.760 --> 00:52:36.900
you

00:52:36.900 --> 00:52:37.120
find

00:52:37.120 --> 00:52:37.240
your

00:52:37.240 --> 00:52:37.480
next

00:52:37.480 --> 00:52:37.680
big

00:52:37.680 --> 00:52:38.000
thing

00:52:38.000 --> 00:52:38.660
visit

00:52:38.660 --> 00:52:39.620
Hired.com

00:52:39.620 --> 00:52:40.240
slash

00:52:40.240 --> 00:52:40.940
Talk Python

00:52:40.940 --> 00:52:41.260
to me

00:52:41.260 --> 00:52:41.660
to get

00:52:41.660 --> 00:52:42.180
five or

00:52:42.180 --> 00:52:42.680
more offers

00:52:42.680 --> 00:52:43.300
with salary

00:52:43.300 --> 00:52:43.900
and equity

00:52:43.900 --> 00:52:44.340
presented

00:52:44.340 --> 00:52:44.760
right up

00:52:44.760 --> 00:52:44.980
front

00:52:44.980 --> 00:52:45.980
and a

00:52:45.980 --> 00:52:46.300
special

00:52:46.300 --> 00:52:46.700
listener

00:52:46.700 --> 00:52:47.020
signing

00:52:47.020 --> 00:52:47.320
bonus

00:52:47.320 --> 00:52:47.520
of

00:52:47.520 --> 00:52:48.140
$4,000

00:52:48.140 --> 00:52:50.000
Codeship

00:52:50.000 --> 00:52:50.400
wants you

00:52:50.400 --> 00:52:50.620
to

00:52:50.620 --> 00:52:51.140
always

00:52:51.140 --> 00:52:51.560
keep

00:52:51.560 --> 00:52:52.020
shipping

00:52:52.020 --> 00:52:52.760
check

00:52:52.760 --> 00:52:52.920
them

00:52:52.920 --> 00:52:53.100
out

00:52:53.100 --> 00:52:53.320
at

00:52:53.320 --> 00:52:54.200
Codeship.com

00:52:54.200 --> 00:52:54.580
and thank

00:52:54.580 --> 00:52:54.920
them on

00:52:54.920 --> 00:52:55.200
Twitter

00:52:55.200 --> 00:52:55.500
via

00:52:55.500 --> 00:52:55.860
at

00:52:55.860 --> 00:52:56.320
Codeship

00:52:56.320 --> 00:52:56.940
don't

00:52:56.940 --> 00:52:57.160
forget

00:52:57.160 --> 00:52:57.320
the

00:52:57.320 --> 00:52:57.620
discount

00:52:57.620 --> 00:52:57.860
code

00:52:57.860 --> 00:52:58.000
for

00:52:58.000 --> 00:52:58.380
listeners

00:52:58.380 --> 00:52:59.020
it's

00:52:59.020 --> 00:52:59.320
easy

00:52:59.320 --> 00:53:00.280
Talk Python

00:53:00.280 --> 00:53:00.560
all

00:53:00.560 --> 00:53:00.880
caps

00:53:00.880 --> 00:53:01.100
no

00:53:01.100 --> 00:53:01.460
spaces

00:53:01.460 --> 00:53:03.140
you can

00:53:03.140 --> 00:53:03.320
find

00:53:03.320 --> 00:53:03.600
the links

00:53:03.600 --> 00:53:03.900
from the

00:53:03.900 --> 00:53:04.140
show

00:53:04.140 --> 00:53:04.480
at

00:53:04.480 --> 00:53:05.800
talkpython.fm

00:53:05.800 --> 00:53:06.680
episodes

00:53:06.680 --> 00:53:07.740
show

00:53:07.740 --> 00:53:08.740
21

00:53:08.740 --> 00:53:09.900
and be

00:53:09.900 --> 00:53:10.180
sure to

00:53:10.180 --> 00:53:10.500
subscribe

00:53:10.500 --> 00:53:10.880
to the

00:53:10.880 --> 00:53:11.080
show

00:53:11.080 --> 00:53:11.940
open your

00:53:11.940 --> 00:53:12.240
favorite

00:53:12.240 --> 00:53:12.800
podcatcher

00:53:12.800 --> 00:53:13.180
and search

00:53:13.180 --> 00:53:13.780
for Python

00:53:13.780 --> 00:53:14.220
we should

00:53:14.220 --> 00:53:14.580
be right

00:53:14.580 --> 00:53:14.780
at the

00:53:14.780 --> 00:53:15.020
top

00:53:15.020 --> 00:53:15.820
you can

00:53:15.820 --> 00:53:16.000
also

00:53:16.000 --> 00:53:16.300
find

00:53:16.300 --> 00:53:16.480
the

00:53:16.480 --> 00:53:16.860
iTunes

00:53:16.860 --> 00:53:17.140
and

00:53:17.140 --> 00:53:17.420
direct

00:53:17.420 --> 00:53:17.840
RSS

00:53:17.840 --> 00:53:18.160
feeds

00:53:18.160 --> 00:53:18.420
in the

00:53:18.420 --> 00:53:18.640
footer

00:53:18.640 --> 00:53:18.800
of the

00:53:18.800 --> 00:53:19.180
website

00:53:19.180 --> 00:53:20.680
our

00:53:20.680 --> 00:53:21.000
theme

00:53:21.000 --> 00:53:21.300
music

00:53:21.300 --> 00:53:21.680
is

00:53:21.680 --> 00:53:22.220
developers

00:53:22.220 --> 00:53:22.700
developers

00:53:22.700 --> 00:53:23.160
developers

00:53:23.160 --> 00:53:23.480
by

00:53:23.480 --> 00:53:23.840
Corey

00:53:23.840 --> 00:53:24.200
Smith

00:53:24.200 --> 00:53:24.500
who

00:53:24.500 --> 00:53:24.680
goes

00:53:24.680 --> 00:53:24.900
by

00:53:24.900 --> 00:53:25.340
Smix

00:53:25.340 --> 00:53:26.120
you can

00:53:26.120 --> 00:53:26.260
hear

00:53:26.260 --> 00:53:26.420
the

00:53:26.420 --> 00:53:26.760
entire

00:53:26.760 --> 00:53:27.240
song

00:53:27.240 --> 00:53:27.600
on

00:53:27.600 --> 00:53:27.840
talk

00:53:27.840 --> 00:53:28.660
python.fm

00:53:28.660 --> 00:53:29.920
this is

00:53:29.920 --> 00:53:30.360
your host

00:53:30.360 --> 00:53:30.820
Michael

00:53:30.820 --> 00:53:31.160
Kennedy

00:53:31.160 --> 00:53:31.900
thanks for

00:53:31.900 --> 00:53:32.220
listening

00:53:32.220 --> 00:53:33.380
Smix

00:53:33.380 --> 00:53:33.960
take us

00:53:33.960 --> 00:53:34.200
out of

00:53:34.200 --> 00:53:34.520
here

00:53:34.520 --> 00:53:35.900
dating

00:53:35.900 --> 00:53:36.320
with my

00:53:36.320 --> 00:53:36.680
voice

00:53:36.680 --> 00:53:37.160
there's no

00:53:37.160 --> 00:53:37.420
norm

00:53:37.420 --> 00:53:37.700
that I

00:53:37.700 --> 00:53:37.860
can

00:53:37.860 --> 00:53:38.100
feel

00:53:38.100 --> 00:53:38.460
within

00:53:38.460 --> 00:53:38.960
haven't

00:53:38.960 --> 00:53:39.140
been

00:53:39.140 --> 00:53:39.700
sleeping

00:53:39.700 --> 00:53:40.180
I've been

00:53:40.180 --> 00:53:40.400
using

00:53:40.400 --> 00:53:40.760
lots

00:53:40.760 --> 00:53:40.960
of

00:53:40.960 --> 00:53:41.300
rest

00:53:41.300 --> 00:53:41.640
I'll

00:53:41.640 --> 00:53:41.860
pass

00:53:41.860 --> 00:53:42.060
the

00:53:42.060 --> 00:53:42.320
mic

00:53:42.320 --> 00:53:42.620
back

00:53:42.620 --> 00:53:42.760
to

00:53:42.760 --> 00:53:42.980
who

00:53:42.980 --> 00:53:43.500
rocked

00:53:43.500 --> 00:53:43.660
it

00:53:43.660 --> 00:53:44.180
best

00:53:44.180 --> 00:53:52.480
I'm first developers, developers, developers, developers, developers.

00:53:52.480 --> 00:53:56.200
Developers, developers, developers, developers, developers.

