YAPC::EU 2011
rurban - Reini Urban
vienna.pm
=> houston.pm
Provide type semantics to enable more compile-time optimizations, to make Perl and compiled Perl smaller and faster.
my TYPE $i; my My::Class $o;
# Declaration only
package TYPE must exist
smaller and faster, ensured at compile-time:
faster method calls, fix types, declarations via class and attributes,
typed arrays + hashes, perfect hashes.
Declare and check type safety. int, double, number, string. params and return values.
Architect. Mainly LISP for several years. Perl as better build system.
rurban maintains cygwin perl since 5.8.8 and some modules: illguts, B::* => 5.10, mainly the "compiler".
No perl dayjob, just for fun. Until now.
In the future a lot more time for the compiler and CORE. Left AVL (automotive industry), went to cPanel to improve the compiler.
FETCH_SCALAR_ATTRIBUTES => New CHECK_SCALAR_ATTRIBUTES callback for my
.
Yes, the language already has one. CORE:
my TYPE $var;Only a few out-of-CORE implementations:
Moose, fields, types, typesafety, Lexical::Types,
Attribute::Types (run-time)
Params: Devel::Declare
, Params::Validate
, Params::Classify
Objects: Class::Meta
, Moose
No standard prototype language, no CPAN prototype parser!
# types 0.xNo standard prototype language, no CPAN prototype parser!
# Devel::Declare, Method::SignaturesAt first a look at CORE types, not the language:
SCALAR (non-strict, VB-like): IV, NV, UV, PV, ...
ARRAY (non-strict): AV
HASH (non-strict): HV
Objects ("stashes", @ISA, declaration)
SCALAR (non-strict, VB-like)
multiple types (IV,NV,PV) per variable, context dependent.
internally upgraded: IV => PVIV => PVNV
SCALAR (non-strict, VB-like)
multiple types (IV,NV,PV) per variable, context dependent.
IV: integer
SCALAR (non-strict, VB-like)
multiple types (IV,NV,PV) per variable, context dependent.
Typed IV: integer unblessed, untied. my int $i;
~SV_SMAGIC =>
SVf_FAKE: no head
=>
SCALAR (non-strict, VB-like)
multiple types (IV,NV,PV) per variable, context dependent.
internally upgraded: IV => NV
SCALAR (non-strict, VB-like)
multiple types (IV,NV,PV) per variable, context dependent.
internally upgraded: IV => NV => PVNV
SCALAR (non-strict, VB-like)
internally upgraded: IV => PVIV => PVNV => "Objects" => Tie
"STASH" - Hierarchical symbol table,
used as package name for Objects. i.e. "Class pointer"
ARRAY (non-strict)
Keys are integers, Values any SCALAR
ARRAY (non-strict)
Keys are integers, Values any SCALAR
@a = ("any", 1, 2.5006, \&code, ['arrayref'], {hashref=>1});ARRAY (non-strict)
Keys are integers, Values any SCALAR - flexible, untyped, big
@a = ("any", 1, 2.5006, \&code, ['arrayref'], {hashref=>1});
Typed ARRAYs (optional, faster, less space)
Keys are integers, Values of one type only (native)
my int @a; $#a=256; # pre-allocate: 256 * sizeof(IV)Untyped:
my @a; $#a=256; # pre-allocate: 256 * sizeof(SV)
AvTYPED && (IOK | NOK | POK)
my int @a;
Declaration already possible now!
perl -we'package int; package main; my int @a;'int must be a package definition.
Note: @a
is currently declared as int
, but not blessed.
HASH untyped: flexible, but big
Keys any SCALAR, Values any SCALAR
%h = ('any' => ["any", 1, 2.5006];Internally: Keys are stringified.
HASH untyped: flexible
Keys any SCALAR, Values any SCALAR
HASH typed: fast, small
Keys STRING only, Values typed
my string %h; $h{'x'} = 'string';HASH typed: directer access, small
Keys STRING only, Values typed
HASH typed: fast, small
Keys STRING only, Values are typed.
my int %h; $h{'any'} = 1;Perfect hashes - guaranteed O(1) lookup, dynamic hash function generation, no collisions
Library cmph BDZ algorithm ("RAM hashing")
my %h :const;
=> untyped perfect hash of unknown sizemy %h :perfect;
=> writable perfect hash
study %h
; => optimize lookup function to perfect hash.
study untyped hash => copies the old perl hash (HV) to new perfect hash (PH).
Perfect hash. Should be typed to optimize implementation.
my int %h :const = ('my' => 1, 'your' => 2);:const
hashes are always :perfect
No need to study with :const and init on declaration.
- Avoid copy from perl hash to perfect hash.
my int %h :perfect;- Declare size in advance.
my int %h :perfect;- :const hash with computed key => values, without study
Idea 1
my int %h :const;Init until length is filled
- :const hash with computed key => values, without study
Idea 2
my int %h :const = map { $h{$_} => $i++} @keys;Initialization on next expression, usually a block.
OBJECTS: typed, but dynamic
run-time changable, mostly no compile-time optimizations possible.
Features: STASH ("class hash"), @ISA (mro), DESTROY
OBJECTS: typed, but dynamic.
Class by STASH, Inheritance by @ISA (mro), magic DESTROY and CLONE methods.
Four method calls possible:
pushmark
ARGS...
gv => GV *Class::sub
entersub
Class->method()
$object->method()
Class->$method()
$object->$method()
Class::sub()
pushmark
const => PV "Class"
ARGS...
method_named => PV "method"
entersub
$object->method()
Class->$method()
$object->$method()
pushmark
padsv => GV *object
ARGS...
method_named => PV "method"
entersub
pushmark
const => PV "Class"
ARGS...
method => GV *method
entersub
pushmark
padsv => GV *object
ARGS...
method => GV *method
entersub
pushmark
const => PV "Class"
ARGS...
method_named => PV "method"
entersub
=>
pushmark
const => PV "Class"
ARGS...
gv => GV *Class::method
entersub
or package Class
:locked or in Moose immutable.
i.e. not changed at run-time.
=> 4% faster method calls.
Note: @Class::ISA
:const = qw(bla);
does not help.
Dynamic method calls are possible to optimize in a similar way, if the object is declared - known class at compile-time.
my My::Class $object = My::Class->new;Inherited methods are optimizable if all classes in path to the final class are :locked, resp. immutable.
All this is possible now, without changing the language.
Just optimized implementations are missing.
I heard that in July 2011 Moose methods of immutable classes are going to be inlined, but what I saw so far it's not using optree changes like these to speed it up.
More compile-time optimizations.
:const for variables
:locked for packages: const @ISA
, no run-time created methods.
types is Artur Bergman's compile-time checking attempt from 2002, after the compiler, B::Generate and optimize.
And before optimizer, which uses types to improve the optree.
types does compile-time type-checking only.
compile-time type-optimizations in optimizer.
Problem: slower, not faster.
The idea is to make programs with use types;
faster, not slower.
And define basic scalar types from CORE
int
, double
and string
The same types and declarations are used in B::CC also to optimize types even further.
B::CC also needs a syntax to optionally declare simple types:
int and double (strict)
So far it was done by magic variable name suffices: $a_i
, $n_d
;
faster, much faster
Strict types as class, and optional type hints as attributes.
my int $foo :const;With use types
you get type-declarations,
partial type-safety, and
type optimizations at compile-time.