Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.programming > #5071 > unrolled thread

compiling python

Started byfir <profesor.fir@gmail.com>
First post2015-01-09 15:36 -0800
Last post2015-01-12 18:28 +0100
Articles 18 — 6 participants

Back to article view | Back to comp.programming


Contents

  compiling python fir <profesor.fir@gmail.com> - 2015-01-09 15:36 -0800
    Re: compiling python BartC <bc@freeuk.com> - 2015-01-09 23:50 +0000
      Re: compiling python fir <profesor.fir@gmail.com> - 2015-01-09 15:59 -0800
        Re: compiling python BartC <bc@freeuk.com> - 2015-01-10 11:45 +0000
          Re: compiling python fir <profesor.fir@gmail.com> - 2015-01-10 07:09 -0800
      Re: compiling python Kaz Kylheku <kaz@kylheku.com> - 2015-01-10 19:19 +0000
        Re: compiling python BartC <bc@freeuk.com> - 2015-01-10 22:02 +0000
          Re: compiling python fir <profesor.fir@gmail.com> - 2015-01-11 10:52 -0800
          Re: compiling python Kaz Kylheku <kaz@kylheku.com> - 2015-01-11 19:24 +0000
            Re: compiling python BartC <bc@freeuk.com> - 2015-01-11 20:23 +0000
            Re: compiling python BartC <bc@freeuk.com> - 2015-01-24 15:01 +0000
              Re: compiling python Kaz Kylheku <kaz@kylheku.com> - 2015-01-24 16:58 +0000
                Re: compiling python Bartc <bc@freeuk.com> - 2015-01-24 19:18 +0000
                  Re: compiling python Kaz Kylheku <kaz@kylheku.com> - 2015-01-24 23:54 +0000
                    Re: compiling python Bartc <bc@freeuk.com> - 2015-01-25 01:26 +0000
    Re: compiling python Robert Wessel <robertwessel2@yahoo.com> - 2015-01-09 18:13 -0600
      Re: compiling python fir <profesor.fir@gmail.com> - 2015-01-09 16:27 -0800
    Re: compiling python Mok-Kong Shen <mok-kong.shen@t-online.de> - 2015-01-12 18:28 +0100

#5071 — compiling python

Fromfir <profesor.fir@gmail.com>
Date2015-01-09 15:36 -0800
Subjectcompiling python
Message-ID<39a759ea-06c0-4e33-93e8-6c5f99fa9303@googlegroups.com>
can someone explain if python can be compiled (to exe) if not why cant be compiled

afaik python is not quite compiled but more like 
interpreter+bytecode contained in exe form..
really there is something that disallows compilation of script languages? I do not
understand this thing, what is really the thing that makes scripts not compilable?

[toc] | [next] | [standalone]


#5072

FromBartC <bc@freeuk.com>
Date2015-01-09 23:50 +0000
Message-ID<cPZrw.416147$Kl4.243354@fx01.am4>
In reply to#5071
On 09/01/2015 23:36, fir wrote:
> can someone explain if python can be compiled (to exe) if not why cant be compiled

Try comp.lang.python. That's quite active.

> afaik python is not quite compiled but more like
> interpreter+bytecode contained in exe form..
> really there is something that disallows compilation of script languages? I do not
> understand this thing, what is really the thing that makes scripts not compilable?

You can certainly create a self-contained executable, but it might not 
be any faster than running the interpreter. Take this bit of code:

  a=b+c

In a scripting language with dynamic types, what would you compile it 
to? You don't know what the types are! They could be integers, floats, 
strings, lists, tuples, ranges, functions, classes or any combination. 
You have to sort this all out at runtime, which is not going to be 
helped by compiling. Especially with Python where /everything/ is 
dynamic and can change from one line to the next.

(There are new techniques for speeding up interpreted code, but they are 
different from the traditional methods for compiling static languages.)

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#5073

Fromfir <profesor.fir@gmail.com>
Date2015-01-09 15:59 -0800
Message-ID<fd777291-69c4-494a-91c6-6ee6c7b28467@googlegroups.com>
In reply to#5072
W dniu sobota, 10 stycznia 2015 00:50:35 UTC+1 użytkownik Bart napisał:
> On 09/01/2015 23:36, fir wrote:
> > can someone explain if python can be compiled (to exe) if not why cant be compiled
> 
> Try comp.lang.python. That's quite active.
> 
> > afaik python is not quite compiled but more like
> > interpreter+bytecode contained in exe form..
> > really there is something that disallows compilation of script languages? I do not
> > understand this thing, what is really the thing that makes scripts not compilable?
> 
> You can certainly create a self-contained executable, but it might not 
> be any faster than running the interpreter. Take this bit of code:
> 
>   a=b+c
> 
> In a scripting language with dynamic types, what would you compile it 
> to? You don't know what the types are! They could be integers, floats, 

i think in most cases (code floe paths) you know, even if you dont know, they are one of the few probably so you could combine different versions and call the appriopriate once with strings once with integers..
no? maybe they are to lazy to do that? 9wrote compiles as maybe it is a bit of work? idont know

this is the only reason?
still i dont see it clearly but it seem that teopretically with an amount of worc it could be compiled..


> strings, lists, tuples, ranges, functions, classes or any combination. 
> You have to sort this all out at runtime, which is not going to be 
> helped by compiling. Especially with Python where /everything/ is 
> dynamic and can change from one line to the next.
> 
> (There are new techniques for speeding up interpreted code, but they are 
> different from the traditional methods for compiling static languages.)
> 
> -- 
> Bartc

[toc] | [prev] | [next] | [standalone]


#5076

FromBartC <bc@freeuk.com>
Date2015-01-10 11:45 +0000
Message-ID<zh8sw.436765$td3.273392@fx34.am4>
In reply to#5073
On 09/01/2015 23:59, fir wrote:
> W dniu sobota, 10 stycznia 2015 00:50:35 UTC+1 użytkownik Bart napisał:

>>    a=b+c
>>
>> In a scripting language with dynamic types, what would you compile it
>> to? You don't know what the types are! They could be integers, floats,
>
> i think in most cases (code floe paths) you know, even if you dont know, they are one of the few probably so you could combine different versions and call the appriopriate once with strings once with integers..
> no? maybe they are to lazy to do that? 9wrote compiles as maybe it is a bit of work? idont know

If your aim is to get a faster Python, then there have been plenty of 
attempts, with varying success. Some might use type inference. (But 
PyPy, the most impressive I've seen, uses rather different methods.)

 >
 > this is the only reason?
 > still i dont see it clearly but it seem that teopretically with an 
amount of worc it could be compiled..

Perhaps you'd like to have go; source codes for Python are readily 
available.

(I've tried compiling for my own interpreter projects: translating 
naively to C source then compiling that. But it was slower than just 
interpreting! I think partly because it was no longer practical to use 
function inlining, and the code was more sprawling compared with a 
compact interpreter core.)

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#5077

Fromfir <profesor.fir@gmail.com>
Date2015-01-10 07:09 -0800
Message-ID<c9fbfad1-e2b2-4d24-bdde-9cf3f0e489db@googlegroups.com>
In reply to#5076
W dniu sobota, 10 stycznia 2015 12:45:39 UTC+1 użytkownik Bart napisał:
> On 09/01/2015 23:59, fir wrote:
> > W dniu sobota, 10 stycznia 2015 00:50:35 UTC+1 użytkownik Bart napisał:
> 
> >>    a=b+c
> >>
> >> In a scripting language with dynamic types, what would you compile it
> >> to? You don't know what the types are! They could be integers, floats,
> >
> > i think in most cases (code floe paths) you know, even if you dont know, they are one of the few probably so you could combine different versions and call the appriopriate once with strings once with integers..
> > no? maybe they are to lazy to do that? 9wrote compiles as maybe it is a bit of work? idont know
> 
> If your aim is to get a faster Python, then there have been plenty of 
> attempts, with varying success. Some might use type inference. (But 
> PyPy, the most impressive I've seen, uses rather different methods.)
> 
>  >
>  > this is the only reason?
>  > still i dont see it clearly but it seem that teopretically with an 
> amount of worc it could be compiled..
> 
> Perhaps you'd like to have go; source codes for Python are readily 
> available.
> 
> (I've tried compiling for my own interpreter projects: translating 
> naively to C source then compiling that. But it was slower than just 
> interpreting! I think partly because it was no longer practical to use 
> function inlining, and the code was more sprawling compared with a 
> compact interpreter core.)
> 
later aim is to get more knowledge, read sources, mybe wrote script compiler myself etc;

now i would like just to understand in robust way what is a trouble of compiling scripting language, is there some or maybe is there none

maybe a bit find to inspect, as i felt tired a bit

[toc] | [prev] | [next] | [standalone]


#5078

FromKaz Kylheku <kaz@kylheku.com>
Date2015-01-10 19:19 +0000
Message-ID<20150110110749.53@kylheku.com>
In reply to#5072
On 2015-01-09, BartC <bc@freeuk.com> wrote:
> On 09/01/2015 23:36, fir wrote:
>> can someone explain if python can be compiled (to exe) if not why cant be compiled
>
> Try comp.lang.python. That's quite active.
>
>> afaik python is not quite compiled but more like
>> interpreter+bytecode contained in exe form..
>> really there is something that disallows compilation of script languages? I do not
>> understand this thing, what is really the thing that makes scripts not compilable?
>
> You can certainly create a self-contained executable, but it might not 
> be any faster than running the interpreter. Take this bit of code:
>
>   a=b+c
>
> In a scripting language with dynamic types, what would you compile it 
> to? You don't know what the types are! They could be integers, floats, 
> strings, lists, tuples, ranges, functions, classes or any combination. 
> You have to sort this all out at runtime, which is not going to be 
> helped by compiling.

Yes, it is still helped by compiling.

Firstly, the compiler knows certain facts, such as that a, b, and c are (let us
say) lexical variables and can generate fast references to them.

A pure interpreter, by contrast, has to look these things up: it looks at a
and wonders, is that a local? A global? It has to do some environmental lookup.

It also might take advantage of knowing that + is a language built-in that
cannot be redefined (let's say).

The compiled code just does something like:

  load R0, offset_b(R29)   ;; R29 is the current closure
  load R1, offset_c(R23)
  call builtin_plus        ;; result is in R0
  store offset_a(R29), R0  ;; store in a

Though builtin_plus does the work, this compiled code saves cycles
compared to the actions which have to be carried out by pure
interpretation, which basically does:

  (eval '(set a (+ a b)) current-env)

eval has to look at "set", invoke the right operator for that,
then set has to analyze the target place a, looking up its location
(probably by calling a function). Then it has to recursively call

  (eval '(+ a b) current-env)

to get the value and so on.


basically, you're neglecting to look at this from the point of view that
a, b and c can be regarded as variables having the generic type "value",
and that the expression is basically just like C:

  a = builtin_plus(b, c);

you wouldn't say that compiling a function call and assignment isn't
beneficial, right? Even if a, b and c are pointers, and the function
actually has to be called.

On top of that, advanced dynamic languages support optimization. If you
promise to the compiler, via declarations, that a, b, and c have certain
types, then it can generate better code.

[toc] | [prev] | [next] | [standalone]


#5079

FromBartC <bc@freeuk.com>
Date2015-01-10 22:02 +0000
Message-ID<bkhsw.531647$dG.86517@fx32.am4>
In reply to#5078
On 10/01/2015 19:19, Kaz Kylheku wrote:
> On 2015-01-09, BartC <bc@freeuk.com> wrote:

>>    a=b+c
>>
>> In a scripting language with dynamic types, what would you compile it
>> to? You don't know what the types are! They could be integers, floats,
>> strings, lists, tuples, ranges, functions, classes or any combination.
>> You have to sort this all out at runtime, which is not going to be
>> helped by compiling.
>
> Yes, it is still helped by compiling.
>
> Firstly, the compiler knows certain facts, such as that a, b, and c are (let us
> say) lexical variables and can generate fast references to them.
>
> A pure interpreter, by contrast, has to look these things up: it looks at a
> and wonders, is that a local? A global? It has to do some environmental lookup.

If we're talking about languages such as Python, then there will already 
be a compilation stage, usually transparent, that converts source code 
to bytecode. I assumed the OP was talking about compilation to native code.

With bytecode, it will already know much of that information.

> basically, you're neglecting to look at this from the point of view that
> a, b and c can be regarded as variables having the generic type "value",
> and that the expression is basically just like C:
>
>    a = builtin_plus(b, c);
>
> you wouldn't say that compiling a function call and assignment isn't
> beneficial, right? Even if a, b and c are pointers, and the function
> actually has to be called.

It's not necessarily beneficial. Most of the work is going to be done 
inside that builtin_plus() function (say a C function that is a 
permanent part of the implementation, while the a=builtin_plus(b,c) part 
is the result of a 'compiling' a bit of script code into C).

The only advantage might be in not having a dispatch loop that finds out 
what the next operation might be.

However, imagine you had 100 lines of a=b+c, then you will have 100 
successive calls to a=builtin_plus(b,c), these are actual calls with 
parameters needing pushing and so on, which are not going to be 
practical to inline.

Now compare with a pure bytecode interpreter implemented with a switch:

while (1) {
  switch (*pcptr) {
  ....
  case kadd:            do_add(); break;
  ....
  }
}

This is an actual example, where do_add() corresponds to 
a=builtin_plus(b,c) (this uses a stack model so there will be extra 
bytecode instructions to push the operands and pop the result).

The compiler will likely inline those handler functions like do_add() 
since there is only one call to each. It will spend those 100 lines in 
this loop, with no function calls and no parameter passing.

> On top of that, advanced dynamic languages support optimization. If you
> promise to the compiler, via declarations, that a, b, and c have certain
> types, then it can generate better code.

That wouldn't count as pure Python then (but as a different version, 
perhaps CPython). When I tried adding type info to my own language 
efforts, the modest gains weren't worth the extra complexity or losing 
the elegance of the language's variant types.

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#5080

Fromfir <profesor.fir@gmail.com>
Date2015-01-11 10:52 -0800
Message-ID<dea393cf-9bd4-457e-b5e2-89a749dad9b4@googlegroups.com>
In reply to#5079
W dniu sobota, 10 stycznia 2015 23:02:51 UTC+1 użytkownik Bart napisał:
> On 10/01/2015 19:19, Kaz Kylheku wrote:
> > On 2015-01-09, BartC <bc@freeuk.com> wrote:
> 
> >>    a=b+c
> >>
> >> In a scripting language with dynamic types, what would you compile it
> >> to? You don't know what the types are! They could be integers, floats,
> >> strings, lists, tuples, ranges, functions, classes or any combination.
> >> You have to sort this all out at runtime, which is not going to be
> >> helped by compiling.
> >
> > Yes, it is still helped by compiling.
> >
> > Firstly, the compiler knows certain facts, such as that a, b, and c are (let us
> > say) lexical variables and can generate fast references to them.
> >
> > A pure interpreter, by contrast, has to look these things up: it looks at a
> > and wonders, is that a local? A global? It has to do some environmental lookup.
> 
> If we're talking about languages such as Python, then there will already 
> be a compilation stage, usually transparent, that converts source code 
> to bytecode. I assumed the OP was talking about compilation to native code.
> 
> With bytecode, it will already know much of that information.
> 
> > basically, you're neglecting to look at this from the point of view that
> > a, b and c can be regarded as variables having the generic type "value",
> > and that the expression is basically just like C:
> >
> >    a = builtin_plus(b, c);
> >
> > you wouldn't say that compiling a function call and assignment isn't
> > beneficial, right? Even if a, b and c are pointers, and the function
> > actually has to be called.
> 
> It's not necessarily beneficial. Most of the work is going to be done 
> inside that builtin_plus() function (say a C function that is a 
> permanent part of the implementation, while the a=builtin_plus(b,c) part 
> is the result of a 'compiling' a bit of script code into C).
> 
> The only advantage might be in not having a dispatch loop that finds out 
> what the next operation might be.
> 
> However, imagine you had 100 lines of a=b+c, then you will have 100 
> successive calls to a=builtin_plus(b,c), these are actual calls with 
> parameters needing pushing and so on, which are not going to be 
> practical to inline.
> 
> Now compare with a pure bytecode interpreter implemented with a switch:
> 
> while (1) {
>   switch (*pcptr) {
>   ....
>   case kadd:            do_add(); break;
>   ....
>   }
> }
> 
> This is an actual example, where do_add() corresponds to 
> a=builtin_plus(b,c) (this uses a stack model so there will be extra 
> bytecode instructions to push the operands and pop the result).
> 
> The compiler will likely inline those handler functions like do_add() 
> since there is only one call to each. It will spend those 100 lines in 
> this loop, with no function calls and no parameter passing.
> 
> > On top of that, advanced dynamic languages support optimization. If you
> > promise to the compiler, via declarations, that a, b, and c have certain
> > types, then it can generate better code.
> 
> That wouldn't count as pure Python then (but as a different version, 
> perhaps CPython). When I tried adding type info to my own language 
> efforts, the modest gains weren't worth the extra complexity or losing 
> the elegance of the language's variant types.
> 
> -- 
> Bartc

so you think that efficiency loss (and python is considered slow) is taken not from lack of compilation but form python shaped structure 
of executable content? 9that i dont know, is doing operations through runtime layers?)

[toc] | [prev] | [next] | [standalone]


#5081

FromKaz Kylheku <kaz@kylheku.com>
Date2015-01-11 19:24 +0000
Message-ID<20150111112226.707@kylheku.com>
In reply to#5079
On 2015-01-10, BartC <bc@freeuk.com> wrote:
> On 10/01/2015 19:19, Kaz Kylheku wrote:
>> On top of that, advanced dynamic languages support optimization. If you
>> promise to the compiler, via declarations, that a, b, and c have certain
>> types, then it can generate better code.
>
> That wouldn't count as pure Python then (but as a different version, 
> perhaps CPython). When I tried adding type info to my own language 
> efforts, the modest gains weren't worth the extra complexity or losing 
> the elegance of the language's variant types.

I see, and whatever you've been able to achieve is representative of
what is possible. Nay, the upper bound.

[toc] | [prev] | [next] | [standalone]


#5082

FromBartC <bc@freeuk.com>
Date2015-01-11 20:23 +0000
Message-ID<OYAsw.573515$dG.559575@fx32.am4>
In reply to#5081
On 11/01/2015 19:24, Kaz Kylheku wrote:
> On 2015-01-10, BartC <bc@freeuk.com> wrote:
>> On 10/01/2015 19:19, Kaz Kylheku wrote:
>>> On top of that, advanced dynamic languages support optimization. If you
>>> promise to the compiler, via declarations, that a, b, and c have certain
>>> types, then it can generate better code.
>>
>> That wouldn't count as pure Python then (but as a different version,
>> perhaps CPython). When I tried adding type info to my own language
>> efforts, the modest gains weren't worth the extra complexity or losing
>> the elegance of the language's variant types.
>
> I see, and whatever you've been able to achieve is representative of
> what is possible. Nay, the upper bound.

As I said, you end up with a different language. It's an inelegant way 
of squeezing extra speed out of it. For example:

function add(a,b) return a+b

This function will work for integers, floats, strings, lists, sets, even 
other user types when the correct overload exists. But it's a bit slow. 
So I create this version:

function add(int a,b)int return a+b

Now it's a bit faster ... for ints. For anything else it now raises an 
error. The natural generics you get with this kind of language goes out 
the window.

My own dynamic, interpreted languages have until recently outperformed 
languages such as Python, Lua, Perl, and Ruby by a magnitude or so. Now 
there are new ways to accelerate those languages, but usually they don't 
involve something as crude as having to add static type info.

I don't need to use such complex methods (and some are very complex) 
because my own effort still performs pretty well. And when I need 
something fast, I just use another of my languages which /is/ statically 
typed.

That can give me an easy 1000% speedup rather than the 50% I might get 
by bolting on static declarations to the other language (at least, 
without changing dramatically changing the structure of the bytecode 
interpreter, but I want to keep that simple and focused).

So my solution is to use two languages, which conveniently both happen 
to have the same syntax; one with dynamic typing, the other static typing.

 > I see, and whatever you've been able to achieve is representative of
 > what is possible. Nay, the upper bound.

That static language has been developed as a replacement for C. Last 
time I checked, that had a typical performance something like 50% slower 
than using gcc with the highest optimisation. That is actually pretty 
good, considering how much effort has gone into gcc.

(30 years ago however my own compilers were generally faster than C 
ones. It's a taken a few years for them to catch up!)

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#5153

FromBartC <bc@freeuk.com>
Date2015-01-24 15:01 +0000
Message-ID<TsOww.430908$BB2.193851@fx35.am4>
In reply to#5081
On 11/01/2015 19:24, Kaz Kylheku wrote:
> On 2015-01-10, BartC <bc@freeuk.com> wrote:
>> On 10/01/2015 19:19, Kaz Kylheku wrote:
>>> On top of that, advanced dynamic languages support optimization. If you
>>> promise to the compiler, via declarations, that a, b, and c have certain
>>> types, then it can generate better code.
>>
>> That wouldn't count as pure Python then (but as a different version,
>> perhaps CPython). When I tried adding type info to my own language
>> efforts, the modest gains weren't worth the extra complexity or losing
>> the elegance of the language's variant types.
>
> I see, and whatever you've been able to achieve is representative of
> what is possible. Nay, the upper bound.

There is a thread now on comp.lang.python ('Python is doomed! Again!') 
about a proposal to add type-hinting to the language. Many are against 
it because it's ugly and clutters up the code. No-one mentioned what the 
benefits are or whether the intention was to make it faster.

(But what I said about not using type info in my own dynamic language is 
not quite right: I do use type info for defining packed arrays and 
structs, and pointers to raw types. Mainly for interfacing with foreign 
functions or with the OS, not for speed. Actually working with such data 
is slower.)

 > I see, and whatever you've been able to achieve is representative of
 > what is possible. Nay, the upper bound.

Take a simple while-loop like this:

def whiletest():
         i=0
         while i<=100000000:
              i=i+1

whiletest()

Execution time:

Python: 120 seconds (normal Python 3 interpreter in C)
MyLang: 3.7 seconds (pure byte-code interpeter)
PyPy:   1.3 seconds (jit/tracing etc etc)
C:      2.7 seconds (native code but unoptimised)
C:      0.8 seconds (native code, optimised)
C:      0.0 seconds (when C discards the code completely, however
                     these implementations could all employ the same
                     trick if they were inclined.)

You can see there is quite a difference (some 30 times slower) between 
my little language and Python.

PyPy does very well, but it excels on simple, repetitive code like this 
(it also needs the while loop to be inside a function otherwise it's 6 
or 7 times slower; Python takes an extra 80 seconds.)

PyPy however is an extremely complex project that has taken years to get 
to this point. And give it something like a simple recursive Fibonacci 
benchmark, and even PyPy is half the speed of my language.

I on the other hand do nothing clever at all. I'm using the same 
approach I was employing in the 1980s. (Just lots of tweaking that 
everyone always says is not worth doing; those people are wrong.)

So I would suggest that perhaps these other implementations have more 
urgent need of type-hinting than I have.

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#5154

FromKaz Kylheku <kaz@kylheku.com>
Date2015-01-24 16:58 +0000
Message-ID<20150124081944.210@kylheku.com>
In reply to#5153
On 2015-01-24, BartC <bc@freeuk.com> wrote:
> On 11/01/2015 19:24, Kaz Kylheku wrote:
>> On 2015-01-10, BartC <bc@freeuk.com> wrote:
>>> On 10/01/2015 19:19, Kaz Kylheku wrote:
>>>> On top of that, advanced dynamic languages support optimization. If you
>>>> promise to the compiler, via declarations, that a, b, and c have certain
>>>> types, then it can generate better code.
>>>
>>> That wouldn't count as pure Python then (but as a different version,
>>> perhaps CPython). When I tried adding type info to my own language
>>> efforts, the modest gains weren't worth the extra complexity or losing
>>> the elegance of the language's variant types.
>>
>> I see, and whatever you've been able to achieve is representative of
>> what is possible. Nay, the upper bound.
>
> There is a thread now on comp.lang.python ('Python is doomed! Again!') 
> about a proposal to add type-hinting to the language. Many are against 
> it because it's ugly and clutters up the code. No-one mentioned what the 
> benefits are or whether the intention was to make it faster.


>
> (But what I said about not using type info in my own dynamic language is 
> not quite right: I do use type info for defining packed arrays and 
> structs, and pointers to raw types. Mainly for interfacing with foreign 
> functions or with the OS, not for speed. Actually working with such data 
> is slower.)
>
> > I see, and whatever you've been able to achieve is representative of
> > what is possible. Nay, the upper bound.
>
> Take a simple while-loop like this:
>
> def whiletest():
>          i=0
>          while i<=100000000:
>               i=i+1
>
> whiletest()
>
> Execution time:
>
> Python: 120 seconds (normal Python 3 interpreter in C)
> MyLang: 3.7 seconds (pure byte-code interpeter)
> PyPy:   1.3 seconds (jit/tracing etc etc)
> C:      2.7 seconds (native code but unoptimised)
> C:      0.8 seconds (native code, optimised)
> C:      0.0 seconds (when C discards the code completely, however
>                      these implementations could all employ the same
>                      trick if they were inclined.)

Yes, well, the entire problem can be cast in terms of not being "inclined".

Python could employ a trick that makes it run in 2.7 seconds, if it were so
inclined, and in 0.8 seconds if it were inclined, all the way down to 0.0
as you note.

> You can see there is quite a difference (some 30 times slower) between 
> my little language and Python.

Clozure Common Lisp:

  (defun test ()
    (do ((i 0 (1+ i)))
        ((> i 100000000))
      (declare
        (type fixnum i)
        (optimize (speed 3) (safety 0)))))

CPU: Intel Core-i5-2310, 2.9 GHz.

  ? (time (test))
  (TEST)
  took 210 milliseconds (0.210 seconds) to run.
  During that period, and with 4 available CPU cores,
       218 milliseconds (0.218 seconds) were spent in user mode
         0 milliseconds (0.000 seconds) were spent in system mode
   32 bytes of memory allocated.
  NIL

  ? (disassemble 'test)
      (recover-fn)                            ;     [0]
      (testl (% temp1) (% temp1))             ;     [5]
      (jne L50)                               ;     [7]
      (pushl (% ebp))                         ;     [9]
      (movl (% esp) (% ebp))                  ;    [10]
      (pushl ($ 0))                           ;    [12]
      (jmp L25)                               ;    [14]
  L16
      (movl (@ -4 (% ebp)) (% arg_z))         ;    [16]
      (addl ($ 4) (% arg_z))                  ;    [19]
      (movl (% arg_z) (@ -4 (% ebp)))         ;    [22]
  L25
      (movl (@ -4 (% ebp)) (% arg_z))         ;    [25]
      (cmpl ($ #x17D78400) (% arg_z))         ;    [28]
      (jle L16)                               ;    [34]
      (movl ($ #x13001) (% arg_z))            ;    [36]
      (leavel)                                ;    [41]
      (retl)                                  ;    [42]
  L50
      (uuo-error-wrong-number-of-args)        ;    [50]

If we take out the declare, it's somehow still just as fast,
even though the code is substantially longer and there are type
checks with branching for various cases which either use
instructions or functions.

  ? (disassemble 'test)
      (recover-fn)                            ;     [0]
      (testl (% temp1) (% temp1))             ;     [5]
      (jne L130)                              ;     [7]
      (pushl (% ebp))                         ;     [9]
      (movl (% esp) (% ebp))                  ;    [10]
      (pushl ($ 0))                           ;    [12]
      (jmp L71)                               ;    [14]
  L16
      (movl (@ -4 (% ebp)) (% arg_z))         ;    [16]
      (testb ($ 3) (% arg_z.b))               ;    [19]
      (jne L46)                               ;    [22]
      (addl ($ 4) (% arg_z))                  ;    [24]
      (jno L68)                               ;    [27]
      (leal (@ 0 (% arg_y)) (% arg_y))        ;    [29]
      (calll (@ .SPFIX-OVERFLOW))             ;    [33]
      (recover-fn)                            ;    [39]
      (jmp L68)                               ;    [44]
  L46
      (movl ($ 4) (% arg_y))                  ;    [46]
      (leal (@ 0 (% arg_y)) (% arg_y))        ;    [51]
      (calll (@ .SPBUILTIN-PLUS))             ;    [57]
      (recover-fn)                            ;    [63]
  L68
      (movl (% arg_z) (@ -4 (% ebp)))         ;    [68]
  L71
      (movl (@ -4 (% ebp)) (% arg_y))         ;    [71]
      (testl ($ 3) (% arg_y))                 ;    [74]
      (jne L92)                               ;    [80]
      (cmpl ($ #x17D78400) (% arg_y))         ;    [82]
      (jle L16)                               ;    [88]
      (jmp L116)                              ;    [90]
  L92
      (movl ($ #x17D78400) (% arg_z))         ;    [92]
      (calll (@ .SPBUILTIN-LE))               ;    [97]
      (recover-fn)                            ;   [103]
      (cmpl ($ #x13001) (% arg_z))            ;   [108]
      (jne L16)                               ;   [114]
  L116
      (movl ($ #x13001) (% arg_z))            ;   [116]
      (leavel)                                ;   [121]
      (retl)                                  ;   [122]
  L130
      (uuo-error-wrong-number-of-args)        ;   [130]

[toc] | [prev] | [next] | [standalone]


#5155

FromBartc <bc@freeuk.com>
Date2015-01-24 19:18 +0000
Message-ID<ma0r5t$nkt$1@dont-email.me>
In reply to#5154
On 24/01/2015 16:58, Kaz Kylheku wrote:
> On 2015-01-24, BartC <bc@freeuk.com> wrote:
>> On 11/01/2015 19:24, Kaz Kylheku wrote:

>>> I see, and whatever you've been able to achieve is representative of
>>> what is possible. Nay, the upper bound.
>>
>> Take a simple while-loop like this:
>>
>> def whiletest():
>>           i=0
>>           while i<=100000000:

Sorry, that should be 1000000000 (1 billion). I needed to reduce it so 
that testing Python 3 wouldn't take so long. All the timings are for a 
count of 1 billion.

(Perhaps trivial language enhancements such as separators in numeric 
literals would be more usefully implemented before bolting on ad-hoc 
type systems!)

>> Python: 120 seconds (normal Python 3 interpreter in C)
>> MyLang: 3.7 seconds (pure byte-code interpeter)
>> PyPy:   1.3 seconds (jit/tracing etc etc)
>> C:      2.7 seconds (native code but unoptimised)
>> C:      0.8 seconds (native code, optimised)
>> C:      0.0 seconds (when C discards the code completely, however
>>                       these implementations could all employ the same
>>                       trick if they were inclined.)
>
> Yes, well, the entire problem can be cast in terms of not being "inclined".
>
> Python could employ a trick that makes it run in 2.7 seconds, if it were so
> inclined, and in 0.8 seconds if it were inclined, all the way down to 0.0
> as you note.

What's the trick? And why isn't it used more often? It it involves using 
Cython or writing anything in C, then it doesn't count. Otherwise we'd 
just use the fastest possible language for any task.

>> You can see there is quite a difference (some 30 times slower) between
>> my little language and Python.
>
> Clozure Common Lisp:
>
>    (defun test ()
>      (do ((i 0 (1+ i)))
>          ((> i 100000000))
>        (declare
>          (type fixnum i)
>          (optimize (speed 3) (safety 0)))))
>
> CPU: Intel Core-i5-2310, 2.9 GHz.
>
>    ? (time (test))
>    (TEST)
>    took 210 milliseconds (0.210 seconds) to run.

OK, let's say 2.1 seconds for a billion. That compares very well with 
the above timings (ignoring the fact that your machine might be faster 
or slower than mine).

Actually when I first tried your code with CLISP, I was quite impressed: 
it finished instantly whatever value I used for the loop. Then I 
discovered I had to add (test) at the end!

CLISP took 65 seconds for the above, so presumably 10-11 minutes for a 
billion. This is on the same machine where my /bytecode interpreter/ 
executes in 3.7 seconds.

This is part of my point: why are there so many slow interpreters 
around? What on earth are they doing for them to take so long? But 
whatever the bottleneck is, the lack of type information is unlikely to 
be the problem.

>    ? (disassemble 'test)

>    L16
>        (movl (@ -4 (% ebp)) (% arg_z))         ;    [16]
>        (addl ($ 4) (% arg_z))                  ;    [19]
>        (movl (% arg_z) (@ -4 (% ebp)))         ;    [22]
>    L25
>        (movl (@ -4 (% ebp)) (% arg_z))         ;    [25]
>        (cmpl ($ #x17D78400) (% arg_z))         ;    [28]
>        (jle L16)                               ;    [34]
>        (movl ($ #x13001) (% arg_z))            ;    [36]
>        (leavel)                                ;    [41]
>        (retl)                                  ;    [42]

> If we take out the declare, it's somehow still just as fast,
> even though the code is substantially longer and there are type
> checks with branching for various cases which either use
> instructions or functions.
>
>    ? (disassemble 'test)
<snip>

So you're saying it doesn't matter too much whether static type 
information is present or not?

But it seems that you have a very effective language which is capable of 
generating fast native code; why doesn't Python do the same? (Maybe it 
could just be translated to your Lisp!)

Anyway we're not comparing the same things. I'm saying my /bytecode/ 
interpreter with /dynamic/ type dispatch can perform quite respectively 
compared with your implementation that directly executes /native code/.

And I don't know how much of a built-in 'do' is for Lisp, but if I use a 
more dedicated loop statement, I can improve the timings a little:

i:=0
while i< 1 billion do      # 3.7 seconds
     ++i
end

for i to 1 billion do      # 2.2 seconds
end

to 1 billion do            # 2.0 seconds
end

As I said, adding type info doesn't buy me much; I'd rather keep the 
language uncluttered.

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#5156

FromKaz Kylheku <kaz@kylheku.com>
Date2015-01-24 23:54 +0000
Message-ID<20150124153738.466@kylheku.com>
In reply to#5155
On 2015-01-24, Bartc <bc@freeuk.com> wrote:
>>> You can see there is quite a difference (some 30 times slower) between
>>> my little language and Python.
>>
>> Clozure Common Lisp:
>>
>>    (defun test ()
>>      (do ((i 0 (1+ i)))
>>          ((> i 100000000))
>>        (declare
>>          (type fixnum i)
>>          (optimize (speed 3) (safety 0)))))
>>
>> CPU: Intel Core-i5-2310, 2.9 GHz.
>>
>>    ? (time (test))
>>    (TEST)
>>    took 210 milliseconds (0.210 seconds) to run.
>
> OK, let's say 2.1 seconds for a billion. That compares very well with 
> the above timings (ignoring the fact that your machine might be faster 
> or slower than mine).

One billion doesn't fit into a fixnum on the 32 bit version of Clozure Common
Lisp. On the 64 bit version I get more meaningful looking timings.

? (time (test))
(TEST)
took 1,329,000 microseconds (1.329000 seconds) to run.

Now with the version with declarations, there is a difference:

? (time (test))
(TEST)
took 345,000 microseconds (0.345000 seconds) to run.

Other data points, using LOOP instead of DO:

? (time (loop for i below 1000000000))
(LOOP FOR I BELOW 1000000000)
took 1,330,000 microseconds (1.330000 seconds) to run.

? (time (loop for i fixnum below 1000000000))
(LOOP FOR I FIXNUM BELOW 1000000000)
took 675,000 microseconds (0.675000 seconds) to run.

> CLISP took 65 seconds for the above, so presumably 10-11 minutes for a 
> billion. This is on the same machine where my /bytecode interpreter/ 
> executes in 3.7 seconds.

In CLISP, you have to compile code explicitly. Try

[1]> (compile 'test)

then repeat. However, note that the type annotations are wrong:

[2]> most-positive-fixnum
16777215

Oops! Looks like fixnums are only 25 bits including sign, on a 32 bit
build.

On a 64 bit Debian box where I have a 64 bit CLISP:

[1]> most-positive-fixnum
281474976710655

Note that in Lisp, if you use declarations, and request (safety 0),
you get undefined behavior if the program lies. Declarations must
be regarded as *promises* to the compiler that you know what you're doing,
rather than request for type checking.

>>    ? (disassemble 'test)
><snip>
>
> So you're saying it doesn't matter too much whether static type 
> information is present or not?

I think the number of iterations may just have been too short for
accurate timing.

> But it seems that you have a very effective language which is capable of 
> generating fast native code; why doesn't Python do the same? (Maybe it 
Clozure Common Lisp was previously known as OpenMCL.

http://en.wikipedia.org/wiki/Macintosh_Common_Lisp#History_of_MCL

There are other Common Lisps with good compilers.

> could just be translated to your Lisp!)

There is such a project: http://common-lisp.net/project/clpython/

[toc] | [prev] | [next] | [standalone]


#5157

FromBartc <bc@freeuk.com>
Date2015-01-25 01:26 +0000
Message-ID<ma1gnu$bvd$1@dont-email.me>
In reply to#5156
On 24/01/2015 23:54, Kaz Kylheku wrote:
> On 2015-01-24, Bartc <bc@freeuk.com> wrote:

>>>     (defun test ()
>>>       (do ((i 0 (1+ i)))
>>>           ((> i 100000000))
>>>         (declare
>>>           (type fixnum i)
>>>           (optimize (speed 3) (safety 0)))))

>> OK, let's say 2.1 seconds for a billion. That compares very well with
>> the above timings (ignoring the fact that your machine might be faster
>> or slower than mine).
>
> One billion doesn't fit into a fixnum on the 32 bit version of Clozure Common
> Lisp. On the 64 bit version I get more meaningful looking timings.
>
> ? (time (test))
> (TEST)
> took 1,329,000 microseconds (1.329000 seconds) to run.
>
> Now with the version with declarations, there is a difference:
>
> ? (time (test))
> (TEST)
> took 345,000 microseconds (0.345000 seconds) to run.

That suggests your machine is at least double the speed of mine, which 
takes a minimum of 0.7 seconds to perform the loop (and 0.0 to not 
execute the loop, but that is of no interest).

I suppose that for high performance dynamic languages with timings at 
this end of the scale, then static type information can be a useful 
extra tweaking method, once all the obvious optimisations have been 
taken care of.

But with un-accelerated Python, Ruby, Perl, etc, those are so 
inefficient that throwing type hints at them would make little 
difference. (Seed7, for example, had an even slower interpreter, despite 
being 100% statically typed. It relied on being compiled to C code to 
get up to speed.)

In my language, type hints could at most double the speed of simple 
benchmarks, but caused many problems with the interpreter because they 
really demanded that custom native code sequences were generated, and 
that data became unboxed, as well as making it harder to have 
auto-ranging numeric types. It would have turned it into a very 
different, less dynamic language.

It is usually much better, IMO, if you can write dynamic code /without/ 
having to be tied down by using hints.

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#5074

FromRobert Wessel <robertwessel2@yahoo.com>
Date2015-01-09 18:13 -0600
Message-ID<3ar0ba1veiahr4nfqi8ht7r7m2d093elom@4ax.com>
In reply to#5071
On Fri, 9 Jan 2015 15:36:09 -0800 (PST), fir <profesor.fir@gmail.com>
wrote:

>can someone explain if python can be compiled (to exe) if not why cant be compiled
>
>afaik python is not quite compiled but more like 
>interpreter+bytecode contained in exe form..
>really there is something that disallows compilation of script languages? I do not
>understand this thing, what is really the thing that makes scripts not compilable?


There are a number of Python compilers and JITs.  A partial list:

https://en.wikipedia.org/wiki/List_of_Python_software#Python_implementations

Which doesn't mean that some of the more dynamic things you can do in
Python are actually going to get faster if you compile them.

I know of someone using PyPy for a reasonably large project, and they
seem happy, but I've no personal experience.

[toc] | [prev] | [next] | [standalone]


#5075

Fromfir <profesor.fir@gmail.com>
Date2015-01-09 16:27 -0800
Message-ID<8d446c57-6a56-4347-92ce-154dcd88dd4f@googlegroups.com>
In reply to#5074
W dniu sobota, 10 stycznia 2015 01:08:54 UTC+1 użytkownik robert...@yahoo.com napisał:
> On Fri, 9 Jan 2015 15:36:09 -0800 (PST), fir <profesor.fir@gmail.com>
> wrote:
> 
> >can someone explain if python can be compiled (to exe) if not why cant be compiled
> >
> >afaik python is not quite compiled but more like 
> >interpreter+bytecode contained in exe form..
> >really there is something that disallows compilation of script languages? I do not
> >understand this thing, what is really the thing that makes scripts not compilable?
> 
> 
> There are a number of Python compilers and JITs.  A partial list:
> 
> https://en.wikipedia.org/wiki/List_of_Python_software#Python_implementations
> 
> Which doesn't mean that some of the more dynamic things you can do in
> Python are actually going to get faster if you compile them.
> 
> I know of someone using PyPy for a reasonably large project, and they
> seem happy, but I've no personal experience.

dont know if this is real static compilation, or just in-proces interpreter or some half-way,many depends on it

[toc] | [prev] | [next] | [standalone]


#5109

FromMok-Kong Shen <mok-kong.shen@t-online.de>
Date2015-01-12 18:28 +0100
Message-ID<m9108k$ssq$1@news.albasani.net>
In reply to#5071
Am 10.01.2015 um 00:36 schrieb fir:
[snip]

Just want to say that in an response to your other thread I have
expressed my personal view of the issue of interpretation vs.
compilation of python.

M. K. Shen

[toc] | [prev] | [standalone]


Back to top | Article view | comp.programming


csiph-web