Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

Slow startup on raspberry pi

by vivat (Initiate)
on Jan 16, 2015 at 10:06 UTC ( #1113472=perlquestion: print w/replies, xml ) Need Help??

vivat has asked for the wisdom of the Perl Monks concerning the following question:

My perl script (ca. 400 lines, uses 10 modules) needs more than 10 seconds until it is loaded on a raspberry pi. It is started with the raspberry pi and therewith the boot time is much longer. Running this script is the only purpose of that raspberry pi. Once running, the performance is good. Is there any option to speed up the startup of the script? Some pre-compilation? I already tried with PAR pp but it did not help.

Replies are listed 'Best First'.
Re: Slow startup on raspberry pi
by marto (Cardinal) on Jan 16, 2015 at 10:21 UTC

    PAR/pp will have a startup hit on first run as it unpacks lots of things. The Raspberry Pi is a fairly low power SoC, however there are optimisations to be made. If you are running the OS from SD card, it's going to be slow, installing the OS to a USB disk (or memory stick) is significantly faster in my experience.

    Consider profiling your code, perhaps there is room for improvement (see Devel::NYTProf). In situations where hardware is 'slow' in comparison to what most people are used to, and resources are scarce performance hogs become more apparent.

    I've not worked with the default installation of Raspbian (Debian built for the Pi) in some time. Here are some notes I made* a long time ago and intended to post (on the topic of Perl on the Pi). The notes are far from complete, some or all items may no longer be current, so please proceed with caution:

    Update: I forgot to include the pre change memory usage.

Re: Slow startup on raspberry pi
by wollmers (Scribe) on Jan 16, 2015 at 12:12 UTC

    Watched the same on Raspberry. A

    # mojo version

    took 7 seconds. Then I profiled it with Devel::NYTProf with the result, that attribute creation (does string eval) of Mojo::Base was called around 160 times. In combination with the slow I/O to SD-card it results in 10 times slower than my Mac Air (Core i5, SSD), which needs around 0.7 seconds for the same.

    Profile your script, and try to tune. Maybe avoid bloated modules (e.g. List::Utils for min()). Or just use better hardware.

      But why should a string eval be particularly slower on a pi?

      If IO matters what about copying the modules in one step to a RAM disk?

      Cheers Rolf

      PS: Je suis Charlie!

        String eval is always slow, and it's generally recommended to avoid them when possible on any platform. It's particularly slow on an Rpi, because Rpis are also slow.

        A RAM disk is not a bad idea if you can spare the memory, but I don't think it will be particularly helpful in your case. Since the loadup time at boot is what matters to you, you'll just move that time from the "perl" invocation to the copy command. You *might* see some gains by loading the modules all together with PAR, but that could easily move the problem from I/O to the CPU (due to decompression).

        The first place I would look is making sure you have a good power supply, and the second place is making sure you have a quality SD card.

        "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

        Sorry, expressed myself misleading. One problem is the slow I/O, where the Raspberry spent 5s of 8s in Mojo::Loader, compared with 194ms of 800ms on a MacAir.

        The other problem is the hughe (bloated?) code which affects the runtime on both systems, but a human does not recognize the slowness on the fast system. On fast systems this large amount of CPU-cycles needed for class-factories or other INIT things does not matter, even if a restart of a webapp with 600 modules needs a few seconds.

        Simple Perl like my $x = shift; is typically 17x slower on the Raspy, some other things have lower factors.

Re: Slow startup on raspberry pi
by LanX (Sage) on Jan 16, 2015 at 10:20 UTC
    Not enough information...

    Try to benchmark which module is slowing down the startup and try to tell us why.

    Cheers Rolf

    PS: Je suis Charlie!

      My script uses following modules:
      use IO::Socket; use Fcntl; use strict; use threads; use threads::shared; use MP3::Info; use List::Util 'shuffle'; use LWP; use Switch; use Astro::Sunrise;
      A simple script just printing "Hello World" needs with this modules more than 6 seconds to load whereby the last module (Astro::Sunrise) needs the longest time (ca. 2,5 s). The load time of the other modules is lower (< 1 second). With my more complex script I have almost the double load time until the first line is executed (with the same modules). Maybe perl is simply not appropriate on low performance platforms except for one-liners and I have to rewrite the stuff in C.

        First thing you should look at on the Rpi is having a good power supply. Cheap old cellphone chargers won't cut it. I've had good success with the Canakit adapter. Since your program is I/O limited, finding a quality SD card is the second thing you should look at. Afraid I'm not as much help for this, but I usually buy Class 10 cards and get along OK.

        Looking at your list of modules, you should get rid of threads and threads::shared, preferably rewriting those pieces with fork(), or perhaps AnyEvent. A threaded perl build is noticeably slower than a non-threaded perl, and exists mainly to do pretend fork()s on Windows.

        (As an aside, I just noticed that the default Raspbian perl5.14.2 is compiled with threads. I'm not sure, but hiveberry may come with a perl without threads.)

        You can also ditch Switch and rewrite those parts as an if/elsif series, or perhaps given/when if you're feeling adventurous:

        Just doing those, I think you'll be able to chew off a few seconds at startup time.

        "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

        Maybe perl is simply not appropriate on low performance platforms except for one-liners and I have to rewrite the stuff in C.

        But I thought earlier you said "Once running, the performance is good"? It sounds like you're just running this script once on boot, like a daemon, or does it get started & stopped more often? If just once on boot, I'm not sure what the problem is, why do you really need to optimize the boot time? I understand the speed might be a bit annoying during development but hey, that's the price for running on that hardware ;-) Maybe you can develop on a desktop machine?

        The Rasperry Pi is in general "slow" by modern standards so if you want to use it you'll have to live with a bit of relative slowness no matter what you do with it - try running startx on it to get a feeling for the speed! FWIW, I've written a bit of Perl for the Pi myself, admittedly with less modules than you're using, and those scripts ran just fine.


        there is special consideration on 'use threads;' - start these as early as possible, and yet they are not lightweight, (although some people argue and have different opinion)

        All in all, is this 'use threads;' really a necessity in your script?

        Starting several scripts in parallel could better do the job, IMO.


        I do have a real advise on how to divide startup time of your use ...; lines by factor of 4,

        Those 'use'-d modules are loaded on the fly by 'use' statement and their object loaded.
        Just build these modules statically, and you're done!

        I have tried this approach on windows only (on linux I only used standard perl and my own ordinary builds at /opt/...)
        On windows, I successfully statically linked perl modules statically into perl executable, fortunately the Win32 makefile allows to do so.

        If startup time is still slow after that, then rip out the Autoloader, so this will avoid usage of a large amount of tiny files, instead most will be loaded quickly.
        Also there is another boost option, I'll let you know on that if needed, ...

        PS. in earlier days, when perl run just fine on 486, it was small and quick, and the problem of slow startup was not on the table.

        Due to the requirements of the modules that you are loading, you are actually reading in a lot more than you think. The actual list is more along the lines of -snip- something too large to actually post here.

        Try using scandeps from Module::ScanDeps against your code (even just the list of use statements) and take a look at everything that Astro::Sunrise is requiring from the DateTime tree.

Re: Slow startup on raspberry pi
by morgon (Priest) on Jan 18, 2015 at 00:30 UTC
    uses 10 modules
    While you may be using only 10 modules directly, those modules use other modules (then these again may use other modules - you get the idea) so in reality your script may be loading dozens or even hundreds of modules under the hood.

    For every module the Pi has to load the file and execute it.

    So there are two reasons of slowness: The slowness of the Pi's CPU and the slowness of the SD-card as a storage medium.

    To mitigate the CPU-slowness you could try to overclock the Pi (this is pretty safe), to mitigate the slowness of the card you could use a USB-stick or a USB hard-drive and set up your perl-environment in such a way that it loads the modules from there.

    I fact you can even set up the Pi in such a way that it loads the whole OS from a USB-device (but you still need an SD-card for booting) which should also speed up the boot process.

      Module::ScanDeps should allow a complete listing of all the modules that are getting called in turn by the loaded modules.

      I've heard good things about B::C in terms of speeding up load times, which might be an option if the script is now "complete" and doesn't require many changes.

Re: Slow startup on raspberry pi
by LanX (Sage) on Jan 17, 2015 at 14:13 UTC
    > Some pre-compilation? I already tried with PAR pp but it did not help.

    You seem to use which is a source filter ... I doubt this plays well with pre compilation or PAR.

    Better avoid source filters altogether.

    Cheers Rolf

    PS: Je suis Charlie!

      Yes, I could easily replace the switch statement by elsif's. But with PAR the start takes longer than the direct start of the script. Even the second run with temp modules from a ramdisk. So PAR is no option anyway.
        So it doesn't look like IO matters much.

        But better get rid of the source filter.

        If you really want factor 4 you'll have to try to reactivate one of the pre compile projects like perlcc or find another way to start an image of the executable.

        I've also looked for a suspend mode but that's not rpi's philosophy. It's supposed to he running constantly. Your requirement is not normal.

        Anyway as long a you don't profile your project we gonna be shooting in the dark.

        So sorry I'm out now.

        Cheers Rolf

        PS: Je suis Charlie!

Re: Slow startup on raspberry pi
by Anonymous Monk on Feb 07, 2015 at 22:47 UTC

    It's very recently gotten easier to throw more hardware at the problem :-)

    Raspberry Pi 2 is now on sale for $35 (the same price as the existing Model B+), featuring:

    • A 900MHz quad-core ARM Cortex-A7 CPU (~6x performance)
    • 1GB LPDDR2 SDRAM (2x memory)
    • Complete compatibility with Raspberry Pi 1

    Because it has an ARMv7 processor, it can run the full range of ARM GNU/Linux distributions, including Snappy Ubuntu Core, as well as Microsoft Windows 10.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1113472]
Approved by marto
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (3)
As of 2023-05-28 19:20 GMT
Find Nodes?
    Voting Booth?

    No recent polls found