Can Ruby, PHP, or Perl create a pre-compiled file for the code like Python?
Asked Answered
M

11

22

For Python, it can create a pre-compiled version file.pyc so that the program can be run without interpreted again. Can Ruby, PHP, and Perl do the same on the command line?

Matta answered 19/5, 2009 at 17:54 Comment(0)
B
31

There is no portable bytecode specification for Ruby, and thus also no standard way to load precompiled bytecode archives. However, almost all Ruby implementations use some kind of bytecode or intcode format, and several of them can dump and reload bytecode archives.

YARV always compiles to bytecode before executing the code, however that is usually only done in memory. There are ways to dump out the bytecode to disk. At the moment, there is no way to read it back in, however. This will change in the future: work is underway on a bytecode verifier for YARV, and once that is done, bytecode can safely be loaded into the VM, without fear of corruption. Also, the JRuby developers have indicated that they are willing to implement a YARV VM emulator inside JRuby, once the YARV bytecode format and verifier are stabilized, so that you could load YARV bytecode into JRuby. (Note that this version is obsolete.)

Rubinius also always compiles to bytecode, and it has a format for compiled files (.rbc files, analogous to JVM .class files) and there is talk about a bytecode archive format (.rba files, analogous to JVM .jar files). There is a chance that Rubinius might implement a YARV emulator, if deploying apps as YARV bytecode ever becomes popular. Also, the JRuby developers have indicated that they are willing to implement a Rubinius bytecode emulator inside JRuby, if Rubinius bytecode becomes a popular way of deploying Ruby apps. (Note that this version is obsolete.)

XRuby is a pure compiler, it compiles Ruby sourcecode straight to JVM bytecode (.class files). You can deploy these .class files just like any other Java application.

JRuby started out as an interpreter, but it has both a JIT compiler and an AOT compiler (jrubyc) that can compile Ruby sourcecode to JVM bytecode (.class files). Also, work is underway to create a new compiler that can compile (type-annotated) Ruby code to JVM bytecode that actually looks like a Java class and can be used from Java code without barriers.

Ruby.NET is a pure compiler that compiles Ruby sourcecode to CIL bytecode (PE .dll or .exe files). You can deploy these just like any other CLI application.

IronRuby also compiles to CIL bytecode, but typically does this in-memory. However, you can pass commandline switches to it, so it dumps the .dll and .exe files out to disk. Once you have those, they can be deployed normally.

BlueRuby automatically pre-parses Ruby sourcecode into BRIL (BlueRuby Intermediate Language), which is basically a serialized parsetree. (See Blue Ruby - A Ruby VM in SAP ABAP(PDF) for details.)

I think (but I am definitely not sure) that there is a way to get Cardinal to dump out Parrot bytecode archives. (Actually, Cardinal only compiles to PAST, and then Parrot takes over, so it would be Parrot's job to dump and load bytecode archives.)

Brecciate answered 19/5, 2009 at 21:40 Comment(5)
By PAST did you mean PASM, the Parrot assembly language?Paste
No, AFAICS Parrot compiles to PAST, not PASM. Which makes sense, because that's the way Parrot is intended to use: PASM and PIR are supposed to be written by humans, PAST by compilers.Define
It seems like the compiled versions of ruby should have a substantial performance improvement, but from benchmarks it doesn't seem like that is true (or not as substantial as I would have thought). Is that true and if so do you know why? Thanks!Tildy
Is mruby portable bytecode specification for Ruby?Glasshouse
@ShallmentMo: No, MRuby is an implementation of Ruby, just like Rubinius, JRuby, Opal (well, technically, it's an implementation of a language "almost like Ruby", but it is not compatible with it), Topaz, Cardinal, YARV, IronRuby, MagLev, MacRuby, XRuby, Ruby.NET, tinyrb, etc.Define
N
13

Perl 5 can dump the bytecodes to disk, but it is buggy and nasty. Perl 6 has a very clean method of creating bytecode executables that Parrot can run.

Perl's just-in-time compilation is fast enough that this doesn't matter in most circumstances. One place where it does matter is in a CGI environment which is what mod_perl is for.

Neuropathy answered 19/5, 2009 at 18:3 Comment(2)
That bytecode thing appears to be broken/removed in 5.10. Waiting for 6Dehiscence
and s/mod_perl/fastcgi/ imho.Dehiscence
S
11

For hysterical raisins, Perl 5 looks for .pmc files ahead of .pm files when searching for module. These files could contain bytecode, though Perl doesn't write bytecode out by default (unlike Python).

Module::Compile (or: what's this PMC thingy?) goes into some more depth about this obscure feature. They're not frequently used, but...

The clever folks who wrote Module::Compile take advantage of this, to pre-compile Perl code into... well, it's still Perl, but it's preprocessed.

Among other benefits, this speeds up loading time and makes debugging easier when using source filters (Perl code modifying Perl source code before being loaded by the interpreter).

Saxecoburggotha answered 19/5, 2009 at 19:1 Comment(2)
@Lars: "hysterical raisins" eq "historical reasons". Perl 5 had support for .pmc files from very early on, but it went unused for many years until being rediscovered by some Perl 6 implementers.Saxecoburggotha
"Historical reasons". It's a popular pun.Define
D
6

Not for PHP, although most PHP setups incorporate a Bytecode Cache that will cache the compiled bytecode so that next time the script runs, the compiled version is run. This speeds up execution considerably.

There's no way I'm aware of to actually get at the bytecode through the command line.

Divorcement answered 19/5, 2009 at 18:0 Comment(0)
P
5

For Perl you can try using B::Bytecode and perlcc. However, both of these are highly experimental. And Perl 6 is coming out soon (theoretically) and will be on Parrot and will use a different bytecode and so all of this will be somewhat moot then.

Paste answered 19/5, 2009 at 18:3 Comment(2)
Perl 6 is coming out before Christmas, but Larry didn't say which year. That said you can start playing with Rakudo (the current leader in Perl 6 implementations) now: rakudo.orgNeuropathy
Silly Larry. I would really like Perl 6 to come out soon. I'm currently tearing my hair out trying to get the manpages for git installed, but once I get that out of the way I may look into a Perl 6 implementation soon. I might go with Pugs because it'd be a cool place to start learning Haskell.Paste
B
3

here are some example magic words for the command-line

perl -MO=Bytecode,-H,-o"Module.pm"c "Module.pm"
Bibliomania answered 20/5, 2009 at 8:17 Comment(0)
T
2

According to the third edition of Programming Perl, it is possible to approximate this in some experimental ways.

Training answered 19/5, 2009 at 18:4 Comment(0)
A
1

If you use Zend Guard on your PHP scripts, it essentially precompiles the scripts to byte-code, which can then be run by the PHP engine if the Zend Optimizer extension is loaded.

So, yes, Zend Guard/Optimizer permits pre-compiled PHP scripts to be used.

Achilles answered 19/5, 2009 at 18:27 Comment(0)
Y
1

For PHP, the Phalanger Project compiles down to .Net assemblies. I'm not sure if thats what you were looking for though.

Yb answered 19/5, 2009 at 18:42 Comment(0)
B
1

Has anyone considered using LLVM's bytecode, instead of a yet-another-custom-bytecode?

Baldwin answered 4/6, 2009 at 8:2 Comment(0)
V
0

Ruby 1.8 doesn't actually use bytecode at all (even internally), so there is no pre-compilation step.

Virile answered 19/5, 2009 at 18:5 Comment(5)
But the current version does.Insuperable
This is simply not true. Almost all implementations of Ruby 1.8 (with only one single exception) can compile to bytecode. In fact, several implementations can only compile, they don't even have an interpreter.Define
@Jörg: There is only one implementation that is itself properly called "Ruby 1.8," and that is version 1.8 of the Ruby interpreter written by Matz. The others are Jruby, Rubinius, etc.Insuperable
JRuby and Rubinius (and XRuby, IronRuby, Ruby.NET, MagLev, tinyrb, ...) are all implementations of Ruby 1.8. And all of them use bytecode. The only implementation of Ruby 1.8 that does not use bytecode is MRI. How can you claim that Ruby 1.8 does not use bytecode, when all implementations, except one, do use bytecode? In my answer I listed no less than 6 different implementations of Ruby 1.8 that not only use bytecode, but can actually do what the original poster wants.Define
And of course the OP asked about Ruby, not Ruby 1.8, so if you add Ruby 1.9 implementations into the mix, you get YARV, Red Sun, HotRuby and Cardinal, all of which use bytecode. And Red Sun and HotRuby even require being able to pre-compile Ruby code, because they run the bytecode VM in the webbrowser and the compiler on the webserver, so they have to be able to compile code on the server, dump it out to disk, download it into the browser and load it up again into the VM.Define

© 2022 - 2024 — McMap. All rights reserved.