⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mi23.htm

📁 一个非常适合初学者入门的有关c++的文档
💻 HTM
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN" "http://www.w3.org/TR/REC-html40/frameset.dtd">
<HTML LANG="EN">
<HEAD>
<TITLE>More Effective C++ | Item 23: Consider alternative libraries</TITLE>
<LINK REL=STYLESHEET HREF=../INTRO/ECMEC.CSS>

<SCRIPT LANGUAGE="Javascript" SRC="../JAVA/COOKIE.JS"></SCRIPT>
<SCRIPT LANGUAGE="Javascript">var imagemax = 0; setCurrentMax(0);</SCRIPT>
<SCRIPT LANGUAGE="Javascript" SRC="../JAVA/DINGBATS.JS"></SCRIPT>
<SCRIPT LANGUAGE="Javascript">
var dingbase = "MI23_DIR.HTM";
var dingtext = "Item M23, P";
if (self == top) {
 top.location.replace(dingbase + this.location.hash);
}
</SCRIPT>

</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" ONLOAD="setResize()">
<!-- SectionName="M23: Consider alternative libraries" -->
<A NAME="41253"></A>
<DIV ALIGN="CENTER"><FONT SIZE="-1">Back to <A HREF="./MI22_FR.HTM" TARGET="_top">Item 22: Consider using op= instead of stand-alone op</A> &nbsp;&nbsp;<BR>&nbsp;&nbsp;Continue to <A HREF="./MI24_FR.HTM" TARGET="_top">Item 24: Understand the costs of virtual functions, multiple inheritance, virtual base classes, and RTTI</A></FONT></DIV>


<P><A NAME="dingp1"></A><font ID="mititle">Item 23: &nbsp;Consider alternative libraries.</font><SCRIPT>create_link(1);</SCRIPT>
</P>

<A NAME="72156"></A>

<A NAME="64354"></A>
<P><A NAME="dingp2"></A>
Library design is an exercise in compromise. The ideal library is small, fast, powerful, flexible, extensible, intuitive, universally available, well supported, free of use restrictions, and bug-free. It is also nonexistent. Libraries optimized for size and speed are typically not portable. Libraries with rich functionality are rarely intuitive. Bug-free libraries are limited in scope. In the real world, you can't have everything; something always has to <NOBR>give.<SCRIPT>create_link(2);</SCRIPT>
</NOBR></P><A NAME="64390"></A>
<P><A NAME="dingp3"></A>
Different designers assign different priorities to these criteria. They thus sacrifice different things in their designs. As a result, it is not uncommon for two libraries offering similar functionality to have quite different performance <NOBR>profiles.<SCRIPT>create_link(3);</SCRIPT>
</NOBR></P><A NAME="64429"></A>
<P><A NAME="dingp4"></A>
As an example, consider the iostream and stdio libraries, both of which should be available to every C++ programmer. The iostream library has several advantages over its C counterpart (see <A HREF="../EC/EI2_FR.HTM#95970" TARGET="_top">Item E2</A>). It's type-safe, for example, and it's extensible. In terms of efficiency, however, the iostream library generally suffers in comparison with stdio, because stdio usually results in executables that are both smaller and faster than those arising from <NOBR>iostreams.<SCRIPT>create_link(4);</SCRIPT>
</NOBR></P><A NAME="41255"></A>
<P><A NAME="dingp5"></A>
Consider first the speed issue. One way to get a feel for the difference in performance between iostreams and stdio is to run benchmark applications using both libraries. Now, it's important to bear in mind that benchmarks lie. Not only is it difficult to come up with a set of inputs that correspond to "typical" usage of a program or library, it's also useless unless you have a reliable way of determining how "typical" you or your clients are. Nevertheless, benchmarks can provide <I>some</I> insight into the comparative performance of different approaches to a problem, so though it would be foolish to rely on them completely, it would also be foolish to ignore <NOBR>them.<SCRIPT>create_link(5);</SCRIPT>
</NOBR></P><A NAME="41256"></A>
<A NAME="p111"></A>
<P><A NAME="dingp6"></A>
Let's examine a simple-minded benchmark program that exercises only the most rudimentary I/O functionality. This program reads 30,000 floating point numbers from standard input and writes them to standard output in a fixed format. The choice between the iostream and stdio libraries is made during compilation and is determined by the preprocessor symbol <CODE>STDIO</CODE>. If this symbol is defined, the stdio library is used, otherwise the iostream library is <NOBR>employed.<SCRIPT>create_link(6);</SCRIPT>
</NOBR></P>
<A NAME="10071"></A>
<UL><PRE>#ifdef STDIO
#include &lt;stdio.h&gt;
#else
#include &lt;iostream&gt;
#include &lt;iomanip&gt;
using namespace std;
#endif

<A NAME="41259"></A>
const int VALUES = 30000;                 // # of values to read/write
<A NAME="41260"></A>
int main()
{
  double d;
<A NAME="41261"></A>
  for (int n = 1; n &lt;= VALUES; ++n) {
#ifdef STDIO
    scanf("%lf", &amp;d);
    printf("%10.5f", d);
#else
    cin &gt;&gt; d;
    cout  &lt;&lt; setw(10)                     // set field width
          &lt;&lt; setprecision(5)              // set decimal places
          &lt;&lt; setiosflags(ios::showpoint)  // keep trailing 0s
          &lt;&lt; setiosflags(ios::fixed)      // use these settings
          &lt;&lt; d;
#endif
<A NAME="41262"></A>
    if (n % 5 == 0) {
#ifdef STDIO
      printf("\n");
#else
      cout &lt;&lt; '\n';
#endif
    }
  }
<A NAME="41263"></A>
  return 0;
}
</PRE>
</UL>

<A NAME="41264"></A>
<P><A NAME="dingp7"></A>
When this program is given the natural logarithms of the positive integers as input, it produces output like <NOBR>this:<SCRIPT>create_link(7);</SCRIPT>
</NOBR></P>
<A NAME="41265"></A>

<UL><PRE><A NAME="p112"></A>0.00000   0.69315   1.09861   1.38629   1.60944
1.79176   1.94591   2.07944   2.19722   2.30259
2.39790   2.48491   2.56495   2.63906   2.70805
2.77259   2.83321   2.89037   2.94444   2.99573
3.04452   3.09104   3.13549   3.17805   3.21888
</PRE>
</UL>

<A NAME="41266"></A>
<P><A NAME="dingp8"></A>
Such output demonstrates, if nothing else, that it's possible to produce fixed-format I/O using iostreams. Of <NOBR>course,<SCRIPT>create_link(8);</SCRIPT>
</NOBR></P>
<A NAME="41267"></A>

<UL><PRE>
cout  &lt;&lt; setw(10)
      &lt;&lt; setprecision(5)
      &lt;&lt; setiosflags(ios::showpoint)
      &lt;&lt; setiosflags(ios::fixed)
      &lt;&lt; d;
</PRE>
</UL>

<A NAME="41268"></A>
<P><A NAME="dingp9"></A> is nowhere near as easy to type <NOBR>as<SCRIPT>create_link(9);</SCRIPT>
</NOBR></P>
<A NAME="41269"></A>
<UL><PRE>  printf("%10.5f", d);
</PRE>
</UL>

<A NAME="41270"></A><P><A NAME="dingp10"></A>
but <CODE>operator&lt;&lt; </CODE>is both type-safe and extensible, and <CODE>printf</CODE> is <NOBR>neither.<SCRIPT>create_link(10);</SCRIPT>
</NOBR></P><A NAME="41271"></A>
<P><A NAME="dingp11"></A>
I have run this program on several combinations of machines, operating systems, and compilers, and in every case the stdio version has been faster. Sometimes it's been only a little faster (about 20%), sometimes it's been substantially faster (nearly 200%), but I've never come across an iostream implementation that was as fast as the corresponding stdio implementation. In addition, the size of this trivial program's executable using stdio tends to be smaller (sometimes <I>much</I> smaller) than the corresponding program using iostreams. (For programs of a realistic size, this difference is rarely <NOBR>significant.)<SCRIPT>create_link(11);</SCRIPT>
</NOBR></P><A NAME="41272"></A>
<P><A NAME="dingp12"></A>
Bear in mind that any efficiency advantages of stdio are highly implementation-dependent, so future implementations of systems I've tested or existing implementations of systems I haven't tested may show a negligible performance difference between iostreams and stdio. In fact, one can reasonably hope to discover an iostream implementation that's <I>faster</I> than stdio, because iostreams determine the types of their operands during compilation, while stdio functions typically parse a format string at <NOBR>runtime.<SCRIPT>create_link(12);</SCRIPT>
</NOBR></P><A NAME="92918"></A>
<P><A NAME="dingp13"></A>
The contrast in performance between iostreams and stdio is just an example, however, it's not the main point. The main point is that different libraries offering similar functionality often feature different performance trade-offs, so once you've identified the bottlenecks in your software (via profiling &#151; see <A HREF="./MI16_FR.HTM#40995" TARGET="_top">Item 16</A>), you should see if it's possible to remove those bottlenecks by replacing one library with another. If your program has an I/O bottleneck, for example, you might consider replacing iostreams with stdio, but if it spends a significant portion of its time on dynamic memory allocation and deallocation, you might see if <A NAME="p113"></A>there are alternative implementations of <CODE>operator</CODE> <CODE>new</CODE> and <CODE>operator</CODE> <CODE>delete</CODE> available (see <A HREF="./MI8_FR.HTM#33985" TARGET="_top">Item 8</A> and <A HREF="../EC/EI10_FR.HTM#1986" TARGET="_top">Item E10</A>). <a name="87960"></a>Because different libraries embody different design decisions regarding efficiency, extensibility, portability, type safety, and other issues, you can sometimes significantly improve the efficiency of your software by switching to libraries whose designers gave more weight to performance considerations than to other <NOBR>factors.<SCRIPT>create_link(13);</SCRIPT>
</NOBR></P>
<DIV ALIGN="CENTER"><FONT SIZE="-1">Back to <A HREF="./MI22_FR.HTM" TARGET="_top">Item 22: Consider using op= instead of stand-alone op</A> &nbsp;&nbsp;<BR>&nbsp;&nbsp;Continue to <A HREF="./MI24_FR.HTM" TARGET="_top">Item 24: Understand the costs of virtual functions, multiple inheritance, virtual base classes, and RTTI</A></FONT></DIV>

</BODY>
</HTML>

⌨️ 快捷键说明

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