📄 ch24_02.htm
字号:
<em class="emphasis">group</em> files) that are apt to be reused. It'sparticularly important to cache entries from the network. Forexample, to cache the return value from<tt class="literal">gethostbyaddr</tt> when you are converting numericaddresses (like <tt class="literal">204.148.40.9</tt>) to names (like"<tt class="literal">www.oreilly.com</tt>"), you can use something like:<blockquote><pre class="programlisting">sub numtoname { local ($_) = @_; unless (defined $numtoname{$_}) { my (@a) = gethostbyaddr(pack('C4', split(/\./)),2); $numtoname{$_} = @a > 0 ? $a[0] : $_; } return $numtoname{$_};}</pre></blockquote></p></li><li><p><a name="INDEX-4231"></a>Avoid unnecessary syscalls. Operating system calls tend to be ratherexpensive. So for example, don't call the <tt class="literal">time</tt> operator when acached value of <tt class="literal">$now</tt> would do. Use the special <tt class="literal">_</tt> filehandle toavoid unnecessary <em class="emphasis">stat</em>(2) calls. On some systems, even a minimalsyscall may execute a thousand instructions.</p></li><li><p><a name="INDEX-4232"></a>Avoid unnecessary <tt class="literal">system</tt> calls. The <tt class="literal">system</tt> function has to fork asubprocess in order to execute the program you specify--or worse, execute ashell to execute the program. This can easily execute amillion instructions.</p></li><li><p><a name="INDEX-4233"></a>Worry about starting subprocesses, but only if they're frequent. Starting a single <em class="emphasis">pwd</em>, <em class="emphasis">hostname</em>, or <em class="emphasis">find</em> process isn't going tohurt you much--after all, a shell starts subprocesses all day long. Wedo occasionally encourage the toolbox approach, believe it or not.</p></li><li><p>Keep track of your working directory yourself rather than calling <em class="emphasis">pwd</em>repeatedly. (A standard module is provided for this. See <tt class="literal">Cwd</tt> in <a href="ch30_01.htm">Chapter 30, "The Standard Perl Library"</a>.)</p></li><li><p><a name="INDEX-4234"></a>Avoid shell metacharacters in commands--pass lists to <tt class="literal">system</tt> and<tt class="literal">exec</tt> where appropriate.</p></li><li><p><a name="INDEX-4235"></a><a name="INDEX-4236"></a>Set the sticky bit on the Perl interpreter on machines without demandpaging:<blockquote><pre class="programlisting">chmod +t /usr/bin/perl</pre></blockquote></p></li><li><p>Allowing built-in functions' arguments to default to <tt class="literal">$_</tt> doesn't make yourprogram faster.</p></li></ul><h3 class="sect2">24.2.2. Space Efficiency</h3><ul><li><p><a name="INDEX-4237"></a>You can use <tt class="literal">vec</tt> for compact integer array storageif the integers are of fixed width. (Integers of variable width canbe stored in a UTF-8 string.)</p></li><li><p>Prefer numeric values over equivalent string values--they require lessmemory.</p></li><li><p>Use <tt class="literal">substr</tt> to store constant-length strings in a longer string.</p></li><li><p>Use the <tt class="literal">Tie::SubstrHash</tt> module for very compact storage of a hash array,if the key and value lengths are fixed.</p></li><li><p>Use <tt class="literal">__END__</tt> and the <tt class="literal">DATA</tt> filehandle to avoid storing program dataas both a string and an array.</p></li><li><p>Prefer <tt class="literal">each</tt> to <tt class="literal">keys</tt> where order doesn't matter.</p></li><li><p>Delete or <tt class="literal">undef</tt> globals that are no longer in use.</p></li><li><p>Use some kind of DBM to store hashes.</p></li><li><p>Use temp files to store arrays.</p></li><li><p>Use pipes to offload processing to other tools.</p></li><li><p>Avoid list operations and entire file slurps.</p></li><li><p>Avoid using <tt class="literal">tr///</tt>. Each <tt class="literal">tr///</tt> expression must store asizable translation table.</p></li><li><p>Don't unroll your loops or inline your subroutines.</p></li></ul><h3 class="sect2">24.2.3. Programmer Efficiency</h3><ul><li><p><a name="INDEX-4238"></a>Use defaults.</p></li><li><p>Use funky shortcut command-line switches like <span class="option">-a</span>, <span class="option">-n</span>, <span class="option">-p</span>,<span class="option">-s</span>, and <span class="option">-i</span>.</p></li><li><p>Use <tt class="literal">for</tt> to mean <tt class="literal">foreach</tt>.</p></li><li><p>Run system commands with backticks.</p></li><li><p>Use <tt class="literal"><*></tt> and such.</p></li><li><p>Use patterns created at run time.</p></li><li><p>Use <tt class="literal">*</tt>, <tt class="literal">+</tt>, and <tt class="literal">{}</tt> liberally in your patterns.</p></li><li><p>Process whole arrays and slurp entire files.</p></li><li><p>Use <tt class="literal">getc</tt>.</p></li><li><p>Use <tt class="literal">$`</tt>, <tt class="literal">$&</tt>, and <tt class="literal">$'</tt>.</p></li><li><p>Don't check error values on <tt class="literal">open</tt>, since <tt class="literal"><</tt><em class="replaceable">HANDLE</em><tt class="literal">></tt> and<tt class="literal">print</tt><em class="replaceable">HANDLE</em> will simply behave as no-ops when given an invalid handle.</p></li><li><p>Don't <tt class="literal">close</tt> your files--they'll be closed on the next <tt class="literal">open</tt>.</p></li><li><p>Don't pass subroutine arguments. Use globals.</p></li><li><p>Don't name your subroutine parameters. You can access them directly as<tt class="literal">$_[</tt><em class="replaceable">EXPR</em><tt class="literal">]</tt>.</p></li><li><p>Use whatever you think of first.</p></li></ul><h3 class="sect2">24.2.4. Maintainer Efficiency</h3><ul><li><p>Don't use defaults.</p></li><li><p>Use <tt class="literal">foreach</tt> to mean <tt class="literal">foreach</tt>.</p></li><li><p>Use meaningful loop labels with <tt class="literal">next</tt> and <tt class="literal">last</tt>.</p></li><li><p>Use meaningful variable names.</p></li><li><p>Use meaningful subroutine names.</p></li><li><p>Put the important thing first on the line using <tt class="literal">and</tt>, <tt class="literal">or</tt>, andstatement modifiers (like <tt class="literal">exit if $done</tt>).</p></li><li><p>Close your files as soon as you're done with them.</p></li><li><p>Use packages, modules, and classes to hide your implementation details.</p></li><li><p>Pass arguments as subroutine parameters.</p></li><li><p>Name your subroutine parameters using <tt class="literal">my</tt>.</p></li><li><p>Parenthesize for clarity.</p></li><li><p>Put in lots of (useful) comments.</p></li><li><p>Include embedded pod documentation.</p></li><li><p><tt class="literal">use warnings</tt>.</p></li><li><p><tt class="literal">use strict</tt>.</p></li></ul><h3 class="sect2">24.2.5. Porter Efficiency</h3><ul><li><p><a name="INDEX-4239"></a>Wave a handsome tip under his nose.</p></li><li><p>Avoid functions that aren't implemented everywhere. You can use <tt class="literal">eval</tt>tests to see what's available.</p></li><li><p>Use the <tt class="literal">Config</tt> module or the <tt class="literal">$^O</tt> variable to find out what kind ofmachine you're running on.</p></li><li><p>Don't expect native float and double to <tt class="literal">pack</tt> and <tt class="literal">unpack</tt> on foreignmachines.</p></li><li><p>Use network byte order (the "<tt class="literal">n</tt>" and "<tt class="literal">N</tt>" formats for <tt class="literal">pack</tt>) whensending binary data over the network.</p></li><li><p>Don't send binary data over the network. Send ASCII. Better, send UTF-8.Better yet, send money.</p></li><li><p>Check <tt class="literal">$]</tt> or <tt class="literal">$^V</tt> to see if the current version supports all thefeatures you use.</p></li><li><p>Don't use <tt class="literal">$]</tt> or <tt class="literal">$^V</tt>. Use <tt class="literal">require</tt> or <tt class="literal">use</tt> with a version number.</p></li><li><p>Put in the <tt class="literal">eval exec</tt> hack even if you don't use it, so your programwill run on those few systems that have Unix-like shells but don'trecognize the <tt class="literal">#!</tt> notation.</p></li><li><p>Put the <tt class="literal">#!/usr/bin/perl</tt> line in even if you don't use it.</p></li><li><p>Test for variants of Unix commands. Some <em class="emphasis">find</em> programs can't handle the <em class="emphasis">-xdev</em> switch,for example.</p></li><li><p>Avoid variant Unix commands if you can do it internally. Unix commandsdon't work too well on MS-DOS or VMS.</p></li><li><p>Put all your scripts and manpages into a single network filesystem that'smounted on all your machines.</p></li><li><p>Publish your module on CPAN. You'll get lots of feedback if it's notportable.</p></li></ul><h3 class="sect2">24.2.6. User Efficiency</h3><ul><li><p><a name="INDEX-4240"></a>Instead of making users enter data line by line, pop users intotheir favorite editor.</p></li><li><p><a name="INDEX-4241"></a><a name="INDEX-4242"></a><a name="INDEX-4243"></a>Better yet, use a GUI like the Perl/Tk extension, where users cancontrol the order of events. (Perl/Tk is available on CPAN.)</p></li><li><p>Put up something for users to read while you continue doing work.</p></li><li><p>Use autoloading so that the program <em class="emphasis">appears</em> to run faster.</p></li><li><p>Give the option of helpful messages at every prompt.</p></li><li><p>Give a helpful usage message if users don't give correct input.</p></li><li><p>Display the default action at every prompt, and maybe a fewalternatives.</p></li><li><p>Choose defaults for beginners. Allow experts to change the defaults.</p></li><li><p>Use single character input where it makes sense.</p></li><li><p>Pattern the interaction after other things the user is familiar with.</p></li><li><p><a name="INDEX-4244"></a>Make error messages clear about what needs fixing. Include allpertinent information such as filename and error code, like this:<blockquote><pre class="programlisting">open(FILE, $file) or die "$0: Can't open $file for reading: $!\n";</pre></blockquote></p></li><li><p>Use <tt class="literal">fork && exit</tt> to detach from the terminal when the rest of the script is just batchprocessing.</p></li><li><p>Allow arguments to come from either the command line or standardinput.</p></li><li><p>Don't put arbitrary limitations into your program.</p></li><li><p>Prefer variable-length fields over fixed-length fields.</p></li><li><p>Use text-oriented network protocols.</p></li><li><p>Tell everyone else to use text-oriented network protocols!</p></li><li><p>Tell everyone else to tell everyone else to use text-oriented network protocols!!!</p></li><li><p>Be vicariously lazy.</p></li><li><p>Be nice.</p></li></ul><a name="INDEX-4245"></a><a name="INDEX-4246"></a><a name="INDEX-4247"></a><!-- BOTTOM NAV BAR --><hr width="515" align="left"><div class="navbar"><table width="515" border="0"><tr><td align="left" valign="top" width="172"><a href="ch24_01.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0"></a></td><td align="center" valign="top" width="171"><a href="index.htm"><img src="../gifs/txthome.gif" alt="Home" border="0"></a></td><td align="right" valign="top" width="172"><a href="ch24_03.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0"></a></td></tr><tr><td align="left" valign="top" width="172">24.1. Common Goofs for Novices</td><td align="center" valign="top" width="171"><a href="index/index.htm"><img src="../gifs/index.gif" alt="Book Index" border="0"></a></td><td align="right" valign="top" width="172">24.3. Programming with Style</td></tr></table></div><hr width="515" align="left"><!-- LIBRARY NAV BAR --><img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p><font size="-1"><a href="copyrght.htm">Copyright © 2001</a> O'Reilly & Associates. All rights reserved.</font></p><map name="library-map"> <area shape="rect" coords="2,-1,79,99" href="../index.htm"><area shape="rect" coords="84,1,157,108" href="../perlnut/index.htm"><area shape="rect" coords="162,2,248,125" href="../prog/index.htm"><area shape="rect" coords="253,2,326,130" href="../advprog/index.htm"><area shape="rect" coords="332,1,407,112" href="../cookbook/index.htm"><area shape="rect" coords="414,2,523,103" href="../sysadmin/index.htm"></map><!-- END OF BODY --></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -