Normal quotes
This commit is contained in:
parent
5e10794a24
commit
18011c595a
352 changed files with 6040 additions and 6040 deletions
38
01-05.md
38
01-05.md
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
The third reason is often fallacious. C library functions are not always
|
||||
written in assembly, nor are they always particularly well-optimized.
|
||||
(In fact, they’re often written for *portability*, which has nothing to
|
||||
do with optimization.) What’s more, they’re general-purpose functions,
|
||||
(In fact, they're often written for *portability*, which has nothing to
|
||||
do with optimization.) What's more, they're general-purpose functions,
|
||||
and often can be outperformed by well-but-not- brilliantly-written code
|
||||
that is well-matched to a specific task. As an example, consider Listing
|
||||
1.5, which uses internal buffering to handle blocks of bytes at a time.
|
||||
|
|
@ -14,7 +14,7 @@ Table 1.1 shows that Listing 1.5 is 2.5 to 4 times faster than Listing
|
|||
uses no assembly at all.
|
||||
|
||||
------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
 *Clearly, you can do well by using special-purpose C code in place of a C library function—if you have a thorough understanding of how the C library function operates and exactly what your application needs done. Otherwise, you’ll end up rewriting C library functions in C, which makes no sense at all.*
|
||||
 *Clearly, you can do well by using special-purpose C code in place of a C library function—if you have a thorough understanding of how the C library function operates and exactly what your application needs done. Otherwise, you'll end up rewriting C library functions in C, which makes no sense at all.*
|
||||
------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
**LISTING 1.5 L1-5.C**
|
||||
|
|
@ -38,17 +38,17 @@ uses no assembly at all.
|
|||
int WorkingLength, LengthCount;
|
||||
|
||||
if ( argc != 2 ) {
|
||||
printf(“usage: checksum filename\n”);
|
||||
printf("usage: checksum filename\n");
|
||||
exit(1);
|
||||
}
|
||||
if ( (Handle = open(argv[1], O_RDONLY | O_BINARY)) == -1 ) {
|
||||
printf(“Can’t open file: %s\n”, argv[1]);
|
||||
printf("Can't open file: %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Get memory in which to buffer the data */
|
||||
if ( (WorkingBuffer = malloc(BUFFER_SIZE)) == NULL ) {
|
||||
printf(“Can’t get enough memory\n”);
|
||||
printf("Can't get enough memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ uses no assembly at all.
|
|||
do {
|
||||
if ( (WorkingLength = read(Handle, WorkingBuffer,
|
||||
BUFFER_SIZE)) == -1 ) {
|
||||
printf(“Error reading file %s\n”, argv[1]);
|
||||
printf("Error reading file %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
/* Checksum this chunk */
|
||||
|
|
@ -72,14 +72,14 @@ uses no assembly at all.
|
|||
} while ( WorkingLength );
|
||||
|
||||
/* Report the result */
|
||||
printf(“The checksum is: %u\n”, Checksum);
|
||||
printf("The checksum is: %u\n", Checksum);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
That brings us to the fourth reason: avoiding an internal-buffered
|
||||
implementation like Listing 1.5 because of the difficulty of coding such
|
||||
an approach. True, it is easier to let a C library function do the work,
|
||||
but it’s not all that hard to do the buffering internally. The key is
|
||||
but it's not all that hard to do the buffering internally. The key is
|
||||
the concept of handling data in *restartable blocks;* that is, reading a
|
||||
chunk of data, operating on the data until it runs out, suspending the
|
||||
operation while more data is read in, and then continuing as though
|
||||
|
|
@ -90,11 +90,11 @@ because checksumming works with one byte at a time, forgetting about
|
|||
each byte immediately after adding it into the total. Listing 1.5 reads
|
||||
in a block of bytes from the file, checksums the bytes in the block, and
|
||||
gets another block, repeating the process until the entire file has been
|
||||
processed. In Chapter 5, we’ll see a more complex restartable block
|
||||
processed. In Chapter 5, we'll see a more complex restartable block
|
||||
implementation, involving searching for text strings.
|
||||
|
||||
At any rate, Listing 1.5 isn’t much more complicated than Listing
|
||||
1.4—and it’s a *lot* faster. Always consider the alternatives; a bit of
|
||||
At any rate, Listing 1.5 isn't much more complicated than Listing
|
||||
1.4—and it's a *lot* faster. Always consider the alternatives; a bit of
|
||||
clever thinking and program redesign can go a long way.
|
||||
|
||||
#### Know How to Turn On the Juice {#Heading12}
|
||||
|
|
@ -103,7 +103,7 @@ I have said time and again that optimization is pointless until the
|
|||
design is settled. When that time comes, however, optimization can
|
||||
indeed make a significant difference. Table 1.1 indicates that the
|
||||
optimized version of Listing 1.5 produced by Microsoft C outperforms an
|
||||
unoptimized version of the same code by more than 60 percent. What’s
|
||||
unoptimized version of the same code by more than 60 percent. What's
|
||||
more, a mostly-assembly version of Listing 1.5, shown in Listings 1.6
|
||||
and 1.7, outperforms even the best-optimized C version of List1.5 by 26
|
||||
percent. These are considerable improvements, well worth pursuing—once
|
||||
|
|
@ -131,17 +131,17 @@ the design has been maxed out.
|
|||
int WorkingLength;
|
||||
|
||||
if ( argc != 2 ) {
|
||||
printf(“usage: checksum filename\n”);
|
||||
printf("usage: checksum filename\n");
|
||||
exit(1);
|
||||
}
|
||||
if ( (Handle = open(argv[1], O_RDONLY | O_BINARY)) == -1 ) {
|
||||
printf(“Can’t open file: %s\n”, argv[1]);
|
||||
printf("Can't open file: %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Get memory in which to buffer the data */
|
||||
if ( (WorkingBuffer = malloc(BUFFER_SIZE)) == NULL ) {
|
||||
printf(“Can’t get enough memory\n”);
|
||||
printf("Can't get enough memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
@ -152,16 +152,16 @@ the design has been maxed out.
|
|||
do {
|
||||
if ( (WorkingLength = read(Handle, WorkingBuffer,
|
||||
BUFFER_SIZE)) == -1 ) {
|
||||
printf(“Error reading file %s\n”, argv[1]);
|
||||
printf("Error reading file %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
/* Checksum this chunk if there’s anything in it */
|
||||
/* Checksum this chunk if there's anything in it */
|
||||
if ( WorkingLength )
|
||||
ChecksumChunk(WorkingBuffer, WorkingLength, &Checksum);
|
||||
} while ( WorkingLength );
|
||||
|
||||
/* Report the result */
|
||||
printf(“The checksum is: %u\n”, Checksum);
|
||||
printf("The checksum is: %u\n", Checksum);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue