3 ms·
I'm not an expert by any means, so please provide correction/feedback if I'm wrong, but I've read that xargs is more efficient because it can send parameters to
by bradleyland 15y ago
I'm not an expert by any means, so please provide correction/feedback if I'm wrong, but I've read that xargs is more efficient because it can send parameters to the cmd in batches. I've read this in contrast to `-exec {}` not `-delete`, however.
For example:
find . -name '*~' -exec 'rm {}'
The statement above executes `rm result` for every result. By contrast:
find . -name '*~' | xargs rm
The example above would group the results and pass them to rm like this:
rm result1 result2 result3 result4
Because I'm not an expert, I don't know how many parmeters it will pass, or if initiation of many new processes has a significant performance impact on newer systems. I would suspect that for anything involving the disk, I/O will be the bottle neck, not process turn-up time.
Anyone have an opinion/insight?
- LukeShu 15y ago-delete will be the fastest because find can do everything, and it already has the file loaded, and doesn't have to do a second lookup. -exec will be slower because for each file it has to spawn a new process (this is where most of the time goes), and then that new process has to look up the file. xargs will be faster than -exec because it will collect a few hundred, or thousand, filenames, and pass them all to one command (the article claims 4096 is the default, on some systems it may be lower). This means that typically, only 3 processes need to spawn: `find', `xargs', and one `rm'; instead of find, and many, many `rm's. Now, xargs is still slower than -delete because it will buffer the filenames, either waiting for the list to end, or 4000 filenames to pass to `rm'. Then, rm must look up the file from the filename. To make my point I just set up a test situation with 1110 files ending with `~', among a total of 2221 files. I tested how fast it is to delete all the files ending with `~' using the 3 following commands: $ find . -name '*~' -delete $ find . -name '*~' -exec rm {} \; $ find . -name '*~' -print0 | xargs -0 rm | real | user | sys -delete | 0.024s | 0.003s | 0.020s -exec | 0.819s | 0.007s | 0.107s xargs | 0.073s | 0.007s | 0.017s I probably should have run those tests multiple times, and taken the average, but meh.
- bradleyland 15y agoVery cool. Thanks for the insight. Mind if I ask how you timed execution? The take aways for me are: * Use find's built-in options where possible * Use xargs where a built-in method isn't available * Use -exec only when nothing else will do
- LukeShu 15y agoI timed it with the `time' command :P
- planckscnst 15y agoMost systems have a find command that supports the "-exec command {} +" option, which does not spawn the command for each result, but instead puts as many arguments as the shell will allow on the command line.