2 * Raster benchmark program for CUPS.
4 * Copyright 2007-2016 by Apple Inc.
5 * Copyright 1997-2006 by Easy Software Products.
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
11 * Include necessary headers...
15 #include <cups/raster.h>
28 #define TEST_WIDTH 1024
29 #define TEST_HEIGHT 1024
31 #define TEST_PASSES 20
38 static double compute_median(double *secs
);
39 static double get_time(void);
40 static void read_test(int fd
);
41 static int run_read_test(void);
42 static void write_test(int fd
, cups_mode_t mode
);
46 * 'main()' - Benchmark the raster read/write functions.
49 int /* O - Exit status */
50 main(int argc
, /* I - Number of command-line args */
51 char *argv
[]) /* I - Command-line arguments */
53 int i
; /* Looping var */
54 int ras_fd
, /* File descriptor for read process */
55 status
; /* Exit status of read process */
56 double start_secs
, /* Start time */
57 write_secs
, /* Write time */
58 read_secs
, /* Read time */
59 pass_secs
[TEST_PASSES
]; /* Total test times */
60 cups_mode_t mode
; /* Write mode */
64 * See if we have anything on the command-line...
67 if (argc
> 2 || (argc
== 2 && strcmp(argv
[1], "-z")))
69 puts("Usage: rasterbench [-z]");
73 mode
= argc
> 1 ? CUPS_RASTER_WRITE_COMPRESSED
: CUPS_RASTER_WRITE
;
79 signal(SIGPIPE
, SIG_IGN
);
82 * Run the tests several times to get a good average...
85 printf("Test read/write speed of %d pages, %dx%d pixels...\n\n",
86 TEST_PAGES
, TEST_WIDTH
, TEST_HEIGHT
);
87 for (i
= 0; i
< TEST_PASSES
; i
++)
89 printf("PASS %2d: ", i
+ 1);
92 ras_fd
= run_read_test();
93 start_secs
= get_time();
95 write_test(ras_fd
, mode
);
97 write_secs
= get_time();
98 printf(" %.3f write,", write_secs
- start_secs
);
104 read_secs
= get_time();
105 pass_secs
[i
] = read_secs
- start_secs
;
106 printf(" %.3f read, %.3f total\n", read_secs
- write_secs
, pass_secs
[i
]);
109 printf("\nMedian Total Time: %.3f seconds per document\n",
110 compute_median(pass_secs
));
117 * 'compute_median()' - Compute the median time for a test.
120 static double /* O - Median time in seconds */
121 compute_median(double *secs
) /* I - Array of time samples */
123 int i
, j
; /* Looping vars */
124 double temp
; /* Swap variable */
128 * Sort the array into ascending order using a quicky bubble sort...
131 for (i
= 0; i
< (TEST_PASSES
- 1); i
++)
132 for (j
= i
+ 1; j
< TEST_PASSES
; j
++)
133 if (secs
[i
] > secs
[j
])
141 * Return the average of the middle two samples...
144 return (0.5 * (secs
[TEST_PASSES
/ 2 - 1] + secs
[TEST_PASSES
/ 2]));
149 * 'get_time()' - Get the current time in seconds.
152 static double /* O - Time in seconds */
155 struct timeval curtime
; /* Current time */
158 gettimeofday(&curtime
, NULL
);
159 return (curtime
.tv_sec
+ 0.000001 * curtime
.tv_usec
);
164 * 'read_test()' - Benchmark the raster read functions.
168 read_test(int fd
) /* I - File descriptor to read from */
170 unsigned y
; /* Looping var */
171 cups_raster_t
*r
; /* Raster stream */
172 cups_page_header2_t header
; /* Page header */
173 unsigned char buffer
[8 * TEST_WIDTH
];
181 if ((r
= cupsRasterOpen(fd
, CUPS_RASTER_READ
)) == NULL
)
183 perror("Unable to create raster input stream");
187 while (cupsRasterReadHeader2(r
, &header
))
189 for (y
= 0; y
< header
.cupsHeight
; y
++)
190 cupsRasterReadPixels(r
, buffer
, header
.cupsBytesPerLine
);
198 * 'run_read_test()' - Run the read test as a child process via pipes.
201 static int /* O - Standard input of child */
204 int ras_pipes
[2]; /* Raster data pipes */
205 int pid
; /* Child process ID */
211 if ((pid
= fork()) < 0)
214 * Fork error - return -1 on error...
225 * Child comes here - read data from the input pipe...
229 read_test(ras_pipes
[0]);
235 * Parent comes here - return the output pipe...
239 return (ras_pipes
[1]);
245 * 'write_test()' - Benchmark the raster write functions.
249 write_test(int fd
, /* I - File descriptor to write to */
250 cups_mode_t mode
) /* I - Write mode */
252 unsigned page
, x
, y
; /* Looping vars */
253 unsigned count
; /* Number of bytes to set */
254 cups_raster_t
*r
; /* Raster stream */
255 cups_page_header2_t header
; /* Page header */
256 unsigned char data
[32][8 * TEST_WIDTH
];
257 /* Raster data to write */
261 * Create a combination of random data and repeated data to simulate
262 * text with some whitespace.
265 CUPS_SRAND(time(NULL
));
267 memset(data
, 0, sizeof(data
));
269 for (y
= 0; y
< 28; y
++)
271 for (x
= CUPS_RAND() & 127, count
= (CUPS_RAND() & 15) + 1;
277 x
+= (CUPS_RAND() & 15) + 1;
278 count
= (CUPS_RAND() & 15) + 1;
280 if (x
>= sizeof(data
[0]))
284 data
[y
][x
] = (unsigned char)CUPS_RAND();
289 * Test write speed...
292 if ((r
= cupsRasterOpen(fd
, mode
)) == NULL
)
294 perror("Unable to create raster output stream");
298 for (page
= 0; page
< TEST_PAGES
; page
++)
300 memset(&header
, 0, sizeof(header
));
301 header
.cupsWidth
= TEST_WIDTH
;
302 header
.cupsHeight
= TEST_HEIGHT
;
303 header
.cupsBytesPerLine
= TEST_WIDTH
;
307 header
.cupsBytesPerLine
*= 4;
308 header
.cupsColorSpace
= CUPS_CSPACE_CMYK
;
309 header
.cupsColorOrder
= CUPS_ORDER_CHUNKED
;
313 header
.cupsColorSpace
= CUPS_CSPACE_K
;
314 header
.cupsColorOrder
= CUPS_ORDER_BANDED
;
319 header
.cupsBytesPerLine
*= 2;
320 header
.cupsBitsPerColor
= 16;
321 header
.cupsBitsPerPixel
= (page
& 1) ? 64 : 16;
325 header
.cupsBitsPerColor
= 8;
326 header
.cupsBitsPerPixel
= (page
& 1) ? 32 : 8;
329 cupsRasterWriteHeader2(r
, &header
);
331 for (y
= 0; y
< TEST_HEIGHT
; y
++)
332 cupsRasterWritePixels(r
, data
[y
& 31], header
.cupsBytesPerLine
);