We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

The Python Compiler

00:00

Formal Metadata

Title
The Python Compiler
Title of Series
Part Number
167
Number of Parts
173
Author
License
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language
Production PlaceBilbao, Euskadi, Spain

Content Metadata

Subject Area
Genre
Abstract
Kay Hayen - The Python Compiler The Python compiler Nuitka has evolved from an absurdly compatible Python to C++ translator into a **statically optimizing Python compiler**. The mere peephole optimization is now accompanied by full function/module level optimization, with more to come, and only increased compatibility. Witness local and module **variable value propagation**, **function in-lining** with suitable code, and graceful degradation with code that uses the full Python power. (This is considered kind of the break through for Nuitka, to be finished for EP.) No compromises need to be made, full language support, all modules work, including extension modules, e.g. PyQt just works. Also new is a plugin framework that allows the user to provide workarounds for the standalone mode (create self contained distributions), do his own type hinting to Nuitka based on e.g. coding conventions, provide his own optimization based on specific knowledge. Ultimately, Nuitka is intended to grow the Python base into fields, where performance is an issue, it will need your help. Scientific Python could largely benefit from future Nuitka. Join us now.
Keywords
Group actionGoodness of fitProjective planeMultiplication signComputer virusLecture/Conference
Physical systemCompilerDemo (music)Web pageAsynchronous Transfer ModeMetropolitan area networkMessage passingModul <Datentyp>Plug-in (computing)MathematicsEscape characterMachine codeRWE DeaFrame problemSystem callType theoryMathematical analysisCuboidMaxima and minimaSoftwareVisual systemIntegrated development environmentOnline helpMereologyFormal languageAndroid (robot)Projective planeMobile WebRight angleCompilerBitGodElectronic mailing listPresentation of a groupSpacetimeMultiplication signOperating systemRevision controlComputer programmingRun time (program lifecycle phase)2 (number)CodeSign (mathematics)Mathematical optimization1 (number)MetrePoint (geometry)WeightDialectJava appletSlide ruleCuboidSequenceArithmetic meanVector potentialSoftwarePressureFunctional (mathematics)Type theorySoftware bugoutputDirection (geometry)Form (programming)TheorySoftware testingSuite (music)Computer animation
NP-hardPort scannerSystem callOrder (biology)Proper mapFlagMetropolitan area networkMachine codeBenchmarkWeb pageCompilerType theoryGamma functionMaxima and minimaSima (architecture)Information systemsModule (mathematics)Interface (computing)Density of statesExtension (kinesiology)Mathematical optimizationPatch (Unix)Projective planeDirectory serviceElectric generatorWebsiteString (computer science)Electronic mailing listCompilerPiType theoryFunctional (mathematics)CodeStatement (computer science)Formal languagePoint (geometry)Computer programmingNumberSlide ruleCompilerRecursionBenchmarkQuicksortTracing (software)Object (grammar)Abstract syntax treeException handlingModule (mathematics)Message passingProcess (computing)EmailParity (mathematics)Constructor (object-oriented programming)BitPropagatorHypermediaVapor barrierRun time (program lifecycle phase)MereologyNetwork topologyComputer fileTypinferenzModule (mathematics)System callDirection (geometry)Abstract syntaxRevision controlDifferent (Kate Ryan album)Logical constantView (database)ExistenceGraph (mathematics)BytecodeXMLComputer animation
Web pageCompilerDemo (music)Port scannerStatement (computer science)Logical constantFrame problemBlock (periodic table)System callFunction (mathematics)Directed setMetropolitan area networkDemo (music)Multiplication signTupleStatement (computer science)Logical constantFunctional (mathematics)ResultantAsynchronous Transfer ModeMathematical analysisSystem callExponential functionException handlingLine (geometry)QuicksortSemantics (computer science)Block (periodic table)Scaling (geometry)CodeComputer animationProgram flowchart
PredictabilityVariable (mathematics)Regulärer Ausdruck <Textverarbeitung>Metropolitan area networkStatement (computer science)Web pageCompilerPersonal area networkDemo (music)Logical constantLocal ringBitException handlingVariable (mathematics)Functional (mathematics)TupleLecture/Conference
Demo (music)Statement (computer science)Logical constantVariable (mathematics)Regulärer Ausdruck <Textverarbeitung>Real numberPort scannerMetropolitan area networkInternet service providerFunctional (mathematics)Computer programmingCodeoutputElectric generatorStatement (computer science)QuicksortMereologyRepresentation (politics)TupleReduction of orderMathematical analysisProjective planeType theoryCompilerMetropolitan area networkFunction (mathematics)ProgrammschleifeMathematical optimizationSet (mathematics)Logical constant
Value-added networkMetropolitan area networkModule (mathematics)Ordinary differential equationInterpreter (computing)Statement (computer science)Logical constantRegulärer Ausdruck <Textverarbeitung>Ext functorFunction (mathematics)Asynchronous Transfer ModeWeb pageCompilerDemo (music)CodeFerry CorstenResultantWordFunctional (mathematics)Local ringVariable (mathematics)Software testingSuite (music)Program flowchartComputer animationXML
Real numberBinary fileMusical ensembleMathematicsSystem callAbstract syntax treeGamma functionMetropolitan area networkModule (mathematics)Server (computing)Modul <Datentyp>Curve fittingLaptopMathematical optimizationCodeRight anglePower (physics)Source code
Machine codeMathematicsWeightMusical ensembleSineWeb pageCompilerMetropolitan area networkAbsolute valueTime evolutionPort scannerMaxima and minimaSoftware developerPlot (narrative)Factory (trading post)Electronic mailing listPatch (Unix)Statement (computer science)EmailPower (physics)Rothe-VerfahrenData typeOnline chatGrand Unified TheorySystem callType theoryFeedbackCountingException handlingSocial classPresentation of a groupMathematical optimizationSystem callFunctional (mathematics)1 (number)CompilerDistribution (mathematics)Electric generatorBranch (computer science)WritingExtension (kinesiology)ResultantCodeMultiplication signFactory (trading post)Tracing (software)InformationVideo gameVirtual machineMereologyProjective planeObject (grammar)NeuroinformatikInstance (computer science)Machine codeConstructor (object-oriented programming)Slide ruleSound effectCompilerIntegerElectronic program guidePoint (geometry)Affine spaceWordFormal languageVariable (mathematics)Order of magnitudeFitness functionPosition operatorImplementationOperator (mathematics)Line (geometry)OracleSoftware testingEvoluteProper mapPlotterDomain nameOrder (biology)WeightElement (mathematics)QuicksortBytecodeBinary codeForm (programming)Module (mathematics)BackupRight angleDefault (computer science)Pairwise comparisonParsingAsynchronous Transfer ModeElectronic mailing listOverhead (computing)Focus (optics)Standard deviationMeta elementComputer animation
Metropolitan area networkModul <Datentyp>Module (mathematics)Pell's equationMereologyStack (abstract data type)Projective planeComputer programmingOcean currentDirection (geometry)ImplementationObject (grammar)Mathematical analysisQuicksortMemory managementElectronic mailing listCountingSemiconductor memorySource code
Boom (sailing)Virtual machineNumberBenchmarkMultiplication signLibrary (computing)Distribution (mathematics)Computer programmingOnline helpMedical imagingRandom number generationMathematical analysisSelectivity (electronic)Point (geometry)Arithmetic meanSoftware developerReal numberTheoryCodeSet (mathematics)MereologyStandard deviationTraffic reportingStack (abstract data type)Lecture/Conference
Transcript: English(auto-generated)
Yes, hello. Welcome to my talk. I'm here as a private entity and hobbyist. I'm not here for a company, but at least now my project got a logo, which you can see on the right side. I have a quick overview of the topics. I did previous talks at your pythons two
and three years ago and these were longer talks. This time I was going for a faster talk. I have some actual good news and I have some problems to share with you. So I'm going to talk about who I am. My name is Kai Hein. I'm a professional from the ATC industry
and I do this as my hobby. It's my spare time effort and my spare time effort of the title of the talk kind of disclosed it already is the Python compiler. I got a bit preposterous
about this, but basically if you see the goals, that makes sense. Show you what it takes. It takes basically nothing. We are going to compile the simple program and the full program material, but there's not going to be a lot of time to look at this.
So that's going to be fast. I'm going to present you with my goals and the plan, how we get here. The last point on the slide, join me is the most important because this project is really high potential and it's limited by the amount of contributors. So far I am
mostly on my own. I have a few people who helped me and sustained parts of the project, but this is not enough. So it's going slower than it could be. Although, as you will see, it's pretty, it's progressing pretty well. Then I will have a look at some details
of Nootka. Nootka, as you know, Python is a very dynamic and complex language and I have taken steps to reduce that problem and there's some common complaints here. Everybody knows that Python is highly dynamic. How could a compiler even work?
Then we look at optimizations, what we have so far. That list got longer recently and actually I'm demoing now here and when I wrote the title of the talk, this didn't work and
it didn't work until maybe last week, the inlining of function calls, which is a, I see this as a breakthrough to the compiler. Technically, practically, it's probably not. Technically, it's very good achievement and what else is going to come?
So, maybe let me start with a name. It's named after my wife Anna and like it was suggested seconds ago, I could have named it like this. I named it after her and she's Russian and in Russian, she's called An Nootka and short form Nootka, which is tricky because
it's pronounced differently when it is written. So, but that is your name and I started it with, after mingling with other projects, PyPy and Cython, to be a fully compatible
compiler that doesn't have to make any compromises and doesn't have to invent a new language and so on. I was thinking out of a box. So, most people see Python as a very powerful tool for some part of the language landscape, but not all and I wanted to take
it to also where performance critical stuff happens. So, sorry. I don't see any time pressure. So, I do this the right way and the right way means that I can do this so it carries all the weight of Python all the time. It's licensed very liberally and
you can use it with everything. So, it's a free software of the most free kind. Most major milestones are now achieved. It's basically working if you want, all you want
is an accelerator. It's going to work on all the operating systems. Android and iOS need some work, but in theory they should work and I know that some people have done some things, but it's still future work. Obviously, the mobile space and Python is
could see some help and maybe Nootka can provide that. So, what does it use? It uses older Python versions and new ones alike, even the latest 3.5 Peter. Anticipating a question
from you, I added support for that. So, it passes the C Python 3.4 test suite running a compiled code and it takes a C++ compiler. I will cover that issue more on later slides.
And it takes your Python code and that is it. So, it's really just a C++ compiler and Nootka and you can compile. So, having a new language that is separate from Python means I lose all the things I like. I put them all on the slides here and I'm trying
to be a bit fast about the presentation, but you know, there's lots of things that you are used to and if it's not Python, but for example, something else, then we just lose it, so I put a kind of stop sign below there. So, very important to me is
if we have a fast Python, it should be a Python. Much like PyPy tries to be one or Jython tries to be a Java dialect, I can switch back and forth. So, the thing I'm trying to do is if you start using Nootka, you are not going to have a price attached. It
doesn't mean that your project is bound to using it. That means if you encounter a bug in Nootka and it stops working, you can just use something else instead. So, my ideas here for performance, and these are very old ideas, I've not done anything actually in this direction yet, and I know that Guido is running around and presenting ideas for
type hints, and everybody asks me, will I support them, and the answer is yes, although technically I would like something that also works during the runtime of Python. So, in his proposal, it's just something that Python very exquisitely ignores and doesn't
use, and I don't like that at all. I want it to be code that actually improves the quality and makes these actual checks, and then the compiler just gets to benefit from the knowledge extracted from such checks. So, the first goal, and one which I met
a couple of years ago, was feature parity with C Python. It's compatible with all the language constructs, and it's also compatible with the runtime. So, QT, LXML, whatever
extension objects there are, you can use them. The compatibility that I have achieved and that I have increased since, it's amazingly high. Basically, my first attempt at Nootka was to make a demonstration that something like a Python compiler actually can fit into
things without having a price, and this is now what I consider a true statement. So, from there on, well, on to the next thing. Some of these projects I mentioned need patches, so PyQT, PySIDE, and so on. Sometimes they make too tight check on what is a function,
so I have a compiled function type, and they were not tolerant about this without patches. So, the next thing is to generate efficient code from that. As you can see, the PyStone benchmark, I achieved a number, two and a
half, and it was only to show if we don't have byte code but have compilation, what can we gain? It's not really worth it. So, I think this sort of speed up is unimportant.
So, what we got new is this code generation is now starting to remove code that is not used, and it's using traces to determine if objects need releases, and as we will
see later, exceptions are now fast. I have a slide about this. So, constant propagation, which is basically just peephole optimization. So, identify as many values and push it forward. So, if you assign a constant into a variable and
use that later on, you generate efficient code. I have just recently achieved that. What I haven't got yet, and which will be an important part to getting any actual improvement that is worthwhile for anybody, is to make type inference and treat strings,
integers, lists, and so on differently. That's only starting to exist. Then, interfacing with C code, the so-called bindings, I had a discussion with a stipend guy this morning.
Nudka will and should be able to understand C types and CFFI and make direct calls. I have a slide about that too, and hints, type hints, doesn't exist. So, not this year. Type hints and so on. So, I have here an outside view of Nudka.
Here, where you can see that on the top left, you have your code, and you put that through Nudka. It can be multiple files. So, Nudka recurses according to your Python graph and just finds your code and produces from that a bunch of C++ files and puts
it in a directory, and then it runs Gons. What typically happens is that people tell me for some reasons that I do not really understand that Sconce is somehow bad. I don't think it is. It does the job, and I have a Sconce file in Nudka, which then can be used to produce a module. So, if you were to deliver an extension module from your Python
code, that's feasible. Even whole packages, or you can produce an executable. So, from a user standpoint, Nudka and your code, that is basically it. Sconce does handle the C++ details, and I get very nice emails from people who said, if you even found my
Microsoft compiler, it just works. It's very easy to use. So, I have a very low barrier of entry. When we look inside, you will find that I have a couple of faces. So,
based on the abstract syntax tree, the same one that Python uses. So, in a sense, I'm reusing the Python parser, which is one of the benefits of not having a separate language. I enter a step called reformulations. So, for example, in Python 2.6, the with statement
got added, and it's, well, I could have a with node, and generate code from that, and actually, first versions of Nudka did that. So, I had a C++ template, and I generated code, which just happened to do the proper thing, the compatible thing, but that's not
how it's done anymore. We now have reformulations, and with these reformulations, the with statement ends up simpler Python. We are going to see a few examples of that. So, I'm speaking very fast, and I try to be fast. The idea is also that you can have your questions asked. So, if you have a question, just raise your hand, and ask questions whenever
you think you have one, please do so. Then we go into optimization, which is basically an endless loop, because optimizing a Python program, you cannot have a single or two pass approach, because after every optimization, any other optimization may become feasible
again. So, it's an endless loop, but it finishes at some point, and then finalization is entered, which just annotates the code a bit more. This then final tree receives the code generation, and then the directory we were seeing. So, that's very typical.
What's probably special is that there is this reformulation step, which tries to make a baby Python out of things. So, time for demo. This is a very simple demo.
It's a Python function, and it has a nested function, and it does local variable assignments, and then it makes this call, which can be inlined, and actually, you and I, as a human,
we can see what happens, and the thing which I'm very proud of is that I now have variable tracing and SSH sufficiently strong to justify that on a global scale, NUEDCA will be able to understand that sort of code and produce a simpler result. So, it
has a verbose mode, and here we see a look into inside what happens there when
it runs. So, there are tried blocks, which is sort of true because of a reformulation. For example, this statement here does an unpacking, and secretly that involves try finally semantics. So, if you get interrupted while unpacking, you get to release something.
So, but the static analysis finds out that the tried blocks can be reduced. It finds out that the assignment to G can be propagated entirely and therefore be dropped, the one
to X, one to Y. The value is then actually propagated, and then in line nine here we have a constant tuple, constant result. We can replace the call to G with a direct call, and we can inline the function. We can discover that previously there was a
variable G, but it now is no longer used, and so it's not assigned, and then it's not initialized anymore. So, this uninitialized variable G, it can be, well, the releasing of it. Should there have been an exception in a Python function, your locals get released.
That's what's behind this, and then we propagate the inline variables, and the variable, build a tuple, and so on, remove all the try handlers, and ultimately we are done with that.
So, for example, this is an even simpler program, but it's a little bit more complicated because it will help me to make a better demonstration. Better in the sense that right
now the unpacking, I started to have analysis years ago for that, but it's not yet sufficient, so I cannot have tuple unpacking and show a full reduction. So, when we run this, as you can see, outputs a lot of findings, and now for easier debugging, I have invented
a XML representation of the node tree, and I use this to test that something is entirely optimized, and as you can see here, we have a statement return that is just a constant.
So, this function f, all it does is a lot of churn around the notion of producing one constant. Obviously, your code is not going to be like this, but it could be if, for
example, the x were an input value of some sort, and then if this was already a partially optimized function for some reason, then these things make sense.
So, we got this. Any questions about this? The question was, is it storing the reduced
Python code anywhere? Actually, that's a cool idea for a project that I have, is to generate Python code from the reduced one. Right now, I only generate c. I would love for somebody to take the internal representation of the optimization and generate Python code from that Python code that is just faster than the other Python code, but since we are
making a Python compiler for a reason, I'm going to c directly, and in c, I'm outputting this, but basically, technically, the internal final representation is not entirely Python anymore. So, as we will see in the reformulation part, for example, while loops and for loops,
they don't exist, so it is a reduced set, but it would be, for example, feasible to create Python code out of that. So, maybe quickly here, oh, no, don't do this, because
I made XML, and because I'm easily confused, I removed the code that is not used, and I had opened it already, but here we go again. So, this is what the generated code,
for example, looks like. So, we have a local variable, return value, initialize it to nothing, then we initialize it to the result, which is a pre-made constant, and we go
to a function, return exit, which checks that it's actually a return value, and then it returns it. So, this has become, in Python world, the most efficient code that you can have.
Obviously, there is more to it. So, we can also do Mercurial. This is something that worked two years ago. It's passing the test suite with Mercurial, so we could compile this now, and actually, I was doing it. It took 13, 35 minutes to compile all
of Mercurial, which is a huge body of code. Right now, NUCCA is not making enough optimizations and discovering enough dead code, but half an hour is pretty okay on this laptop without
power. So, generated code, looks like this. I will be quick. So, now it's C code. When I initially started out, I was aware that this is a very ambitious project. So, the
only reason I dared even start it was because C++11, the new C++ language, was having so much cool new features that convinced me that code generation would be relatively simple now. So, the gap between C++11 and Python was relatively small. It turns out
that, for example, C++ exceptions suck, and in-place operations of Python are optimizable, but that doesn't fit into one object only one thing. So, I went to C++03 and then to C++, which is basically just C with some C++ elements, but no class, no types.
And it's going to be C99 soon enough. So, I'm going to skip something. So, as an evolution three years ago, I'm talking now about the C++11 one, the blue part, that was the
code generation. So, I had achieved something phenomenal, and that was a compiler which was capable of integrating with all that Python landscape and made things faster, which was tremendous. But the other part, they are so small, you can barely see them, parser
optimization, there was basically only loophole, peephole optimization three years ago. Two years ago, I went to C++03, and the code generation got a lot more done, and reformulation started to appear, and optimization become bigger. And right now, code generation
has become really stupid, and optimization is carrying the day. So now, these reformulations, I'm making some overhead there using temporary variables and so on. I can now optimize them away. So, availability, I have a high focus on correctness. So, it's available in a stable
and a develop form. The develop form is also better than other stable projects I content, and I have a factory where I publish things that are not finished yet. For example, the inlining code is right now on a factory branch. There's not just Git, there's RPMs
and so on. Lots of people are already using Utica. This is my most important slide, so I want you to join the project. Help me, I will guide you, and I'm going to show one thing I have to cover for correctness. You see the Oracle of Delphi. Delphi means
I can use CPython and compare with Python. So, testing for correctness, it's a dream. It's very easy. For performance, it's much harder. It's a race, and I have ideas, and what I would like you to do is to help me come up and develop with a tool that will
help us give a user feedback for performance. Because if you now compile your code, it may not be faster at all. It may even be slower, and we wouldn't know why. There's no feedback. There's no idea which function is slower or faster and how much.
There needs to be a tool. I need somebody with an interest to help me out with this and rescue us. So, this is the most important thing I meant to say. I would leave the rest of the time, I hope it's still 10 minutes, for questions if you have them.
In my opinion, which Python language constructs were making co-generation the hardest? I think technically, once we are able to inline meta classes and various effects, I think they will not be an issue, and they are very, very easy.
Technically, classes and instances need a lot of babysitting, especially under Python 2, to be correct. So, that was an issue, and I had a huge amount of difficulties with in-place operation.
And exceptions, and exceptions are totally a nightmare. Reference counting is no fun, which is why I developed a compiler tool, so you do not have to write C code ever again. So, next question. For what?
The default type to me right now is object. So, the question was, how to handle it if something doesn't have a type. Right now, Newton-Kerr is basically using no type information at all yet.
What it will do, and let me show you this, in the future, it will be able to understand, for example, C types, and they make direct calls. But right now, everything is an object, be it a list, string, integer. I'm barely, I'm not using the knowledge yet. I will start to make, now that I have this tracing capability,
I can produce proper traces of Python. I will be able to trace the lists and make optimizations dedicated to types, but I don't have it yet. I'm integrating with libPython, and it's PyObject asterisk.
It's a standard Python object. It's like you wrote C extension code. Another question? Yes? I tried various compilers. Obviously, on the C level, there's still always something to gain,
and I'm trying to be clever and smart about code I generate, and I find the Microsoft compiler to be terrible, and it will probably be better. But technically, Newton-Kerr should be in a position to understand Python. So the example that I showed you,
it gains by an order of magnitude performance by just inlining a function call. I don't have time to show the slide now, but if I just avoid a function call of Python, I can have speedups in the domain of 20 fold and so on. And maybe on top of that, with a C compiler,
you can add a few percents again. Yes, Thomas? Also, some feedback. I just ran all the backup from Utica, and it worked. Yeah, that's also ... There was a PyCon talk in 2014, and the presenter also said it just works. I throw things at it. What you just tried is also something called ...
It's a standalone mode. I'm not mentioning that because I'm not interested in it, but it means it will also pack all the things together and allow your distribution to other machines. Something people also expect from a compiler is to be able to take the code to another machine. My interest is mostly in acceleration,
and I'm solving this as a sidekick. But the feedback is it just works, and it's at the point where I'm surprised if something doesn't work. For standalone, I'm not surprised if something doesn't work because it's very hairy with extension modules often.
Yes. Yes, the bytecode is incredibly smaller. Definitely, there's no need to talk about it. A binary, which contains the Python implementation
and uses it, it's larger. But I don't think it's anywhere near important issue, and obviously, you will be much faster with the smaller you are. But yeah, it's larger, but it's still small binaries.
So, if we can have a look at HGX, it's 31 megabytes, I think. Ah, yes, to confuse users. That's a very important part of my project.
So, suppose the program you compile is named HG. What is going to be the resulting name without overwriting it? I want to put it alongside, and I've made good experience with .exe. It's relatively rare that a Python program exists as .exe.
So, but I'm getting questions, and please take note. This one will run on Linux despite its name. And you can rename it. It will still work. So, if you despise the name.
I think I'm using stack memory allocation, yes. And I would definitely, what I will need is some sort of list implementation that is not malloc driven.
If I know the size, and if I know enough sufficient things, I will use stack memory, yes. Try it real fast.
Yeah, the question is if I take advantage of ref counting, I try to do this. So, I'm not always taking a ref count when CPython does, but it's a very marginal gain. The real direction must be to avoid Python objects
wherever we can, and we will see how far this gets. But, of course, where I can, I will have this analysis and know that I don't have to take another ref count because I will be holding one already. Thomas.
I don't really use the way to get rid of them? No. There is no. He's asking about standalone, and the standalone distributions, if you want to copy it to another machine, basically, due to the incompleteness of code removal, it includes the standard library
and all the libraries that standard library uses, and so you end up with a larger set. So, the distribution, I don't think it's huge, but it's like a Python installation, I suppose. Yes? I don't have real world benchmarks
because that defies the purpose of benchmarks. I know that PyPy is really cool now with presenting real world programs and how PyPy stacks up to this. I have this idea about Valgrind. All my benchmarking I'm doing with Valgrind, and Valgrind gives me ticks, so I don't have to run many times,
and I can make analysis directly, and I want your help, or I will do it myself, but I want your help to create a tool which will run the program in Python, and run the program in Utica, and compare the two, and make a highlighting of what parts are fast and slow,
and so I can get, you as a user can get an image, how much speed up do I get in my program, and it should be simple enough to just run your program under another tool and get a report. So, it's all laudable to have these benchmarks
with synthetic code, but I would actually like to empower us, me and the developers of Nuclr and the users. I don't know if we can make this tool, and the sad truth is right now there's nothing. Basically, I just have random numbers of something,
and I'm working very hard on getting to somewhere, but like I said, I have a time, and I don't have a panic to be fast in everything, and tomorrow, and right now I am only starting to wonder about actual performance, so this is now where I want to know how good I am.
Okay, thank you so much. Thank you for being here, and for the good questions.