d797e3c88e
Open the file only if matching on content is needed. Use QFileInfo::filePath() instead of QFileInfo::absoluteFilePath() in QMimeDatabase::mimeTypeForFile(). filePath() does much less work, and so is faster. Thiago Macieira helpfully explained in a review comment why the absolute path is not useful for correctness here: "Nothing needs absolute paths within the same application that would resolve the relative path to absolute. You only need an absolute path if you're communicating with another application that may be in a different directory." QMimeDatabase::mimeTypeForFile() checks fileInfo.isDir(), so the fileName.endsWith(QLatin1Char('/')) check in QMimeDatabasePrivate::mimeTypeForFileNameAndData() was redundant when called from this function. The other two callers of that function now check this condition before opening IO devices. This improves performance of the two QMimeDatabase::mimeTypeForFileNameAndData() overloads in the corner case. Refactor and optimize QMimeDatabasePrivate::findByFileName() and its usages. Previously each caller constructed a QFileInfo object and passed QFileInfo::fileName() into this function. Now the callers simply pass an absolute or relative path to a file into this function, which then uses QFileSystemEntry::fileName() to exclude the path. Constructing QFileInfo is relatively expensive, so this change slightly improves performance. Optimize QMimeDatabasePrivate::loadProviders() by calling static QFileInfo::exists() instead of constructing a QFileInfo object and calling the non-static QFileInfo::exists() overload. Note that the QFileInfo object was always created, even if QFileInfo::exists() under an `if` and an `#if` was never called. The following table contains the average results of the added benchmark tst_QMimeDatabase::benchMimeTypeForFile() on my GNU/Linux system before and at this commit. The numbers denote milliseconds per iteration. data row tag before at MatchDefault: archive 0.029 0.016 OpenDocument Text 0.029 0.015 existent archive with extension 0.039 0.025 existent C with extension 0.033 0.020 existent text file with extension 0.033 0.020 existent C w/o extension 0.076 0.074 existent patch w/o extension 0.11 0.105 existent archive w/o extension 0.069 0.066 MatchExtension: archive 0.012 0.0115 OpenDocument Text 0.0115 0.011 existent archive with extension 0.017 0.016 existent C with extension 0.011 0.011 existent text file with extension 0.011 0.011 existent C w/o extension 0.016 0.0155 existent patch w/o extension 0.013 0.012 existent archive w/o extension 0.013 0.012 MatchContent: archive 0.019 0.012 OpenDocument Text 0.019 0.012 existent archive with extension 0.053 0.051 existent C with extension 0.056 0.0545 existent text file with extension 0.058 0.056 existent C w/o extension 0.0605 0.059 existent patch w/o extension 0.10 0.099 existent archive w/o extension 0.057 0.054 Change-Id: Idb541656e073a2c4822ace3f4da412f29f2351f8 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: David Faure <david.faure@kdab.com> |
||
---|---|---|
.. | ||
corelib | ||
dbus | ||
gui | ||
network | ||
plugins/imageformats/jpeg | ||
sql | ||
testlib | ||
widgets | ||
CMakeLists.txt | ||
README |
The most reliable way of running benchmarks is to do it in an otherwise idle system. On a busy system, the results will vary according to the other tasks demanding attention in the system. We have managed to obtain quite reliable results by doing the following on Linux (and you need root): - switching the scheduler to a Real-Time mode - setting the processor affinity to one single processor - disabling the other thread of the same core This should work rather well for CPU-intensive tasks. A task that is in Real- Time mode will simply not be preempted by the OS. But if you make OS syscalls, especially I/O ones, your task will be de-scheduled. Note that this includes page faults, so if you can, make sure your benchmark's warmup code paths touch most of the data. To do this you need a tool called schedtool (package schedtool), from http://freequaos.host.sk/schedtool/ From this point on, we are using CPU0 for all tasks: If you have a Hyperthreaded multi-core processor (Core-i5 and Core-i7), you have to disable the other thread of the same core as CPU0. To discover which one it is: $ cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list This will print something like 0,4, meaning that CPUs 0 and 4 are sibling threads on the same core. So we'll turn CPU 4 off: (as root) # echo 0 > /sys/devices/system/cpu/cpu4/online To turn it back on, echo 1 into the same file. To run a task on CPU 0 exclusively, using FIFO RT priority 10, you run the following: (as root) # schedtool -F -p 10 -a 1 -e ./taskname For example: # schedtool -F -p 10 -a 1 -e ./tst_bench_qstring -tickcounter Warning: if your task livelocks or takes far too long to complete, your system may be unusable for a long time, especially if you don't have other cores to run stuff on. To prevent that, run it before schedtool and time it. You can also limit the CPU time that the task is allowed to take. Run in the same shell as you'll run schedtool: $ ulimit -s 300 To limit to 300 seconds (5 minutes) If your task runs away, it will get a SIGXCPU after consuming 5 minutes of CPU time (5 minutes running at 100%). If your app is multithreaded, you may want to give it more CPUs, like CPU0 and CPU1 with -a 3 (it's a bitmask). For best results, you should disable ALL other cores and threads of the same processor. The new Core-i7 have one processor with 4 cores, each core can run 2 threads; the older Mac Pros have two processors with 4 cores each. So on those Mac Pros, you'd disable cores 1, 2 and 3, while on the Core-i7, you'll need to disable all other CPUs. However, disabling just the sibling thread seems to produce very reliable results for me already, with variance often below 0.5% (even though there are some measurable spikes). Other things to try: Running the benchmark with highest priority, i.e. "sudo nice -19" usually produces stable results on some machines. If the benchmark also involves displaying something on the screen (on X11), running it with "-sync" is a must. Though, in that case the "real" cost is not correct, but it is useful to discover regressions. Also; not many people know about ionice (1) ionice - get/set program io scheduling class and priority