perlfaq3.html

来自「perl教程」· HTML 代码 · 共 1,053 行 · 第 1/5 页

HTML
1,053
字号
Tie::SubstrHash module can also help for certain types of data
structure.  If you're working with specialist data structures
(matrices, for instance) modules that implement these in C may use
less memory than equivalent Perl modules.</p>
<p>Another thing to try is learning whether your Perl was compiled with
the system malloc or with Perl's builtin malloc.  Whichever one it
is, try using the other one and see whether this makes a difference.
Information about malloc is in the <em>INSTALL</em> file in the source
distribution.  You can find out whether you are using perl's malloc by
typing <code>perl -V:usemymalloc</code>.</p>
<p>Of course, the best way to save memory is to not do anything to waste
it in the first place. Good programming practices can go a long way
toward this:</p>
<ul>
<li><strong><a name="item_don_27t_slurp_21">Don't slurp!</a></strong>

<p>Don't read an entire file into memory if you can process it line
by line. Or more concretely, use a loop like this:</p>
<pre>
        <span class="comment">#</span>
        <span class="comment"># Good Idea</span>
        <span class="comment">#</span>
        <span class="keyword">while</span> <span class="operator">(&lt;</span><span class="variable">FILE</span><span class="operator">&gt;)</span> <span class="operator">{</span>
           <span class="comment"># ...</span>
        <span class="operator">}</span>
</pre>
<p>instead of this:</p>
<pre>
        <span class="comment">#</span>
        <span class="comment"># Bad Idea</span>
        <span class="comment">#</span>
        <span class="variable">@data</span> <span class="operator">=</span> <span class="operator">&lt;</span><span class="variable">FILE</span><span class="operator">&gt;;</span>
        <span class="keyword">foreach</span> <span class="operator">(</span><span class="variable">@data</span><span class="operator">)</span> <span class="operator">{</span>
            <span class="comment"># ...</span>
        <span class="operator">}</span>
</pre>
<p>When the files you're processing are small, it doesn't much matter which
way you do it, but it makes a huge difference when they start getting
larger.</p>
</li>
<li><strong><a name="item_use_map_and_grep_selectively">Use map and grep selectively</a></strong>

<p>Remember that both map and grep expect a LIST argument, so doing this:</p>
<pre>
        <span class="variable">@wanted</span> <span class="operator">=</span> <span class="keyword">grep</span> <span class="operator">{</span><span class="regex">/pattern/</span><span class="operator">}</span> <span class="operator">&lt;</span><span class="variable">FILE</span><span class="operator">&gt;;</span>
</pre>
<p>will cause the entire file to be slurped. For large files, it's better
to loop:</p>
<pre>
        <span class="keyword">while</span> <span class="operator">(&lt;</span><span class="variable">FILE</span><span class="operator">&gt;)</span> <span class="operator">{</span>
                <span class="keyword">push</span><span class="operator">(</span><span class="variable">@wanted</span><span class="operator">,</span> <span class="variable">$_</span><span class="operator">)</span> <span class="keyword">if</span> <span class="regex">/pattern/</span><span class="operator">;</span>
        <span class="operator">}</span>
</pre>
</li>
<li><strong><a name="item_avoid_unnecessary_quotes_and_stringification">Avoid unnecessary quotes and stringification</a></strong>

<p>Don't quote large strings unless absolutely necessary:</p>
<pre>
        <span class="keyword">my</span> <span class="variable">$copy</span> <span class="operator">=</span> <span class="string">"$large_string"</span><span class="operator">;</span>
</pre>
<p>makes 2 copies of $large_string (one for $copy and another for the
quotes), whereas</p>
<pre>
        <span class="keyword">my</span> <span class="variable">$copy</span> <span class="operator">=</span> <span class="variable">$large_string</span><span class="operator">;</span>
</pre>
<p>only makes one copy.</p>
<p>Ditto for stringifying large arrays:</p>
<pre>
        <span class="operator">{</span>
                <span class="keyword">local</span> <span class="variable">$,</span> <span class="operator">=</span> <span class="string">"\n"</span><span class="operator">;</span>
                <span class="keyword">print</span> <span class="variable">@big_array</span><span class="operator">;</span>
        <span class="operator">}</span>
</pre>
<p>is much more memory-efficient than either</p>
<pre>
        <span class="keyword">print</span> <span class="keyword">join</span> <span class="string">"\n"</span><span class="operator">,</span> <span class="variable">@big_array</span><span class="operator">;</span>
</pre>
<p>or</p>
<pre>
        <span class="operator">{</span>
                <span class="keyword">local</span> <span class="variable">$"</span> <span class="operator">=</span> <span class="string">"\n"</span><span class="operator">;</span>
                <span class="keyword">print</span> <span class="string">"@big_array"</span><span class="operator">;</span>
        <span class="operator">}</span>
</pre>
</li>
<li><strong><a name="item_pass_by_reference">Pass by reference</a></strong>

<p>Pass arrays and hashes by reference, not by value. For one thing, it's
the only way to pass multiple lists or hashes (or both) in a single
call/return. It also avoids creating a copy of all the contents. This
requires some judgment, however, because any changes will be propagated
back to the original data. If you really want to mangle (er, modify) a
copy, you'll have to sacrifice the memory needed to make one.</p>
</li>
<li><strong><a name="item_tie_large_variables_to_disk_2e">Tie large variables to disk.</a></strong>

<p>For &quot;big&quot; data stores (i.e. ones that exceed available memory) consider
using one of the DB modules to store it on disk instead of in RAM. This
will incur a penalty in access time, but that's probably better than
causing your hard disk to thrash due to massive swapping.</p>
</li>
</ul>
<p>
</p>
<h2><a name="is_it_safe_to_return_a_reference_to_local_or_lexical_data">Is it safe to return a reference to local or lexical data?</a></h2>
<p>Yes. Perl's garbage collection system takes care of this so
everything works out right.</p>
<pre>
    <span class="keyword">sub</span><span class="variable"> makeone </span><span class="operator">{</span>
        <span class="keyword">my</span> <span class="variable">@a</span> <span class="operator">=</span> <span class="operator">(</span> <span class="number">1</span> <span class="operator">..</span> <span class="number">10</span> <span class="operator">);</span>
        <span class="keyword">return</span> <span class="operator">\</span><span class="variable">@a</span><span class="operator">;</span>
    <span class="operator">}</span>
</pre>
<pre>
    <span class="keyword">for</span> <span class="operator">(</span> <span class="number">1</span> <span class="operator">..</span> <span class="number">10</span> <span class="operator">)</span> <span class="operator">{</span>
        <span class="keyword">push</span> <span class="variable">@many</span><span class="operator">,</span> <span class="variable">makeone</span><span class="operator">();</span>
    <span class="operator">}</span>
</pre>
<pre>
    <span class="keyword">print</span> <span class="variable">$many</span><span class="operator">[</span><span class="number">4</span><span class="operator">][</span><span class="number">5</span><span class="operator">]</span><span class="operator">,</span> <span class="string">"\n"</span><span class="operator">;</span>
</pre>
<pre>
    <span class="keyword">print</span> <span class="string">"@many\n"</span><span class="operator">;</span>
</pre>
<p>
</p>
<h2><a name="how_can_i_free_an_array_or_hash_so_my_program_shrinks">How can I free an array or hash so my program shrinks?</a></h2>
<p>(contributed by Michael Carman)</p>
<p>You usually can't. Memory allocated to lexicals (i.e. <a href="../../lib/Pod/perlfunc.html#item_my"><code>my()</code></a> variables)
cannot be reclaimed or reused even if they go out of scope. It is
reserved in case the variables come back into scope. Memory allocated
to global variables can be reused (within your program) by using
undef()ing and/or delete().</p>
<p>On most operating systems, memory allocated to a program can never be
returned to the system. That's why long-running programs sometimes re-
exec themselves. Some operating systems (notably, systems that use
<code>mmap(2)</code> for allocating large chunks of memory) can reclaim memory that
is no longer used, but on such systems, perl must be configured and
compiled to use the OS's malloc, not perl's.</p>
<p>In general, memory allocation and de-allocation isn't something you can
or should be worrying about much in Perl.</p>
<p>See also &quot;How can I make my Perl program take less memory?&quot;</p>
<p>
</p>
<h2><a name="how_can_i_make_my_cgi_script_more_efficient">How can I make my CGI script more efficient?</a></h2>
<p>Beyond the normal measures described to make general Perl programs
faster or smaller, a CGI program has additional issues.  It may be run
several times per second.  Given that each time it runs it will need
to be re-compiled and will often allocate a megabyte or more of system
memory, this can be a killer.  Compiling into C <strong>isn't going to help
you</strong> because the process start-up overhead is where the bottleneck is.</p>
<p>There are two popular ways to avoid this overhead.  One solution
involves running the Apache HTTP server (available from
<a href="http://www.apache.org/">http://www.apache.org/</a> ) with either of the mod_perl or mod_fastcgi
plugin modules.</p>
<p>With mod_perl and the Apache::Registry module (distributed with
mod_perl), httpd will run with an embedded Perl interpreter which
pre-compiles your script and then executes it within the same address
space without forking.  The Apache extension also gives Perl access to
the internal server API, so modules written in Perl can do just about
anything a module written in C can.  For more on mod_perl, see
<a href="http://perl.apache.org/">http://perl.apache.org/</a></p>
<p>With the FCGI module (from CPAN) and the mod_fastcgi
module (available from <a href="http://www.fastcgi.com/">http://www.fastcgi.com/</a> ) each of your Perl
programs becomes a permanent CGI daemon process.</p>
<p>Both of these solutions can have far-reaching effects on your system
and on the way you write your CGI programs, so investigate them with
care.</p>
<p>See <a href="http://www.cpan.org/modules/by-category/15_World_Wide_Web_HTML_HTTP_CGI/">http://www.cpan.org/modules/by-category/15_World_Wide_Web_HTML_HTTP_CGI/</a> .</p>
<p>
</p>
<h2><a name="how_can_i_hide_the_source_for_my_perl_program">How can I hide the source for my Perl program?</a></h2>
<p>Delete it. :-) Seriously, there are a number of (mostly
unsatisfactory) solutions with varying levels of &quot;security&quot;.</p>
<p>First of all, however, you <em>can't</em> take away read permission, because
the source code has to be readable in order to be compiled and
interpreted.  (That doesn't mean that a CGI script's source is
readable by people on the web, though--only by people with access to
the filesystem.)  So you have to leave the permissions at the socially
friendly 0755 level.</p>
<p>Some people regard this as a security problem.  If your program does
insecure things and relies on people not knowing how to exploit those
insecurities, it is not secure.  It is often possible for someone to
determine the insecure things and exploit them without viewing the
source.  Security through obscurity, the name for hiding your bugs
instead of fixing them, is little security indeed.</p>
<p>You can try using encryption via source filters (Starting from Perl
5.8 the Filter::Simple and Filter::Util::Call modules are included in
the standard distribution), but any decent programmer will be able to
decrypt it.  You can try using the byte code compiler and interpreter
described below, but the curious might still be able to de-compile it.
You can try using the native-code compiler described below, but
crackers might be able to disassemble it.  These pose varying degrees
of difficulty to people wanting to get at your code, but none can
definitively conceal it (true of every language, not just Perl).</p>
<p>It is very easy to recover the source of Perl programs.  You simply
feed the program to the perl interpreter and use the modules in
the B:: hierarchy.  The B::Deparse module should be able to
defeat most attempts to hide source.  Again, this is not
unique to Perl.</p>
<p>If you're concerned about people profiting from your code, then the
bottom line is that nothing but a restrictive license will give you
legal security.  License your software and pepper it with threatening
statements like &quot;This is unpublished proprietary software of XYZ Corp.
Your access to it does not give you permission to use it blah blah
blah.&quot;  We are not lawyers, of course, so you should see a lawyer if
you want to be sure your license's wording will stand up in court.</p>
<p>
</p>
<h2><a name="how_can_i_compile_my_perl_program_into_byte_code_or_c">How can I compile my Perl program into byte code or C?</a></h2>
<p>(contributed by brian d foy)</p>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?