> On Jun 25, 2018, at 16:19, Tomasz Rola <rto...@ceti.pl> wrote: > > On Sun, Jun 24, 2018 at 10:53:37PM -0400, Steve Litt wrote: >> On Thu, 21 Jun 2018 00:56:04 +0200 >> Tomasz Rola <rto...@ceti.pl> wrote: >> > [...] >>> Craps. I have consulted OpenBSD's manpage for dd and there is no >>> mention of iflag. So this will not work on OpenBSD. I will have to >>> rethink this, sorry. >>> >> >> Untested... >> >> int main(int argc, char* argv[]){ >> long l = atod(argv[1]); >> while(l--){ >> if (c = getc(STDIN) != EOF) >> putc(c, STDOUT); >> else >> break; >> } >> return 0; >> } >> >> I haven't tested it so it might not be exactly right, and of course >> error handling would need to be added, but you know what I mean. IIRC >> getc() and putc() are very well buffered so it will be fast. In my >> youth I wrote similar functions using low level read() and write() and >> doing my own buffering, and those things were *really* fast, but I >> think that's overkill in this century. >> >> As far as finding command line tools that do it, if that's becoming >> hard to do, why not just write a 10 line program? > > Actually, I have written few such programs to satiate my own curiosity > - I was dragged away from computer and in the meantime, others joined > thread and even wrote nice buffered version of solution in C. I pitted > this solution against my programs (in C, with fgetc/fputc and Common > Lisp, with read-sequence/write-sequence) and head-c.c was many times > faster (about hundred or more times) than my programs. > > I am not sure if there is performance difference between fgetc/fputc > and getc/putc. Man says getc are macros around fgetc. Might be worth > checking, but I guess no difference. > > My curiosity also "wanted" to know how much of performance hit was to > be expected when writing best to my knowledge optimised Common Lisp vs > simplistic C - they were similar in performance, with CL compiled by > SBCL and few times slower, and head-c.c had beaten them both by many > lengths. I am a bit surprised that in CL, performance was about the > same, whether reading one byte or many at once. Perhaps I will find a > way to speed it up some more. > > As of finding command line tools, I had working script in about an > hour (and buggy one in few minutes). Buggy, because "dd | dd" is bad > idea, and after finding better options for using dd in my script - > which worked, but under Linux - I had also found out they would not > work in OpenBSD. > > So, I consider it a worthy lesson for myself. Next time, I might just > fire up Emacs and write a script in CL (mostly, because this is what > is comfy for me nowadays, and I will not object against having compiled > script for free). Or something similar, or maybe even do it in C, why > not. > > BTW, the version of nread.sh (improved options) was on par with > head-c.c, so writing a script with right things inside is very good > choice, too. If the script actually works :-) . > > While the speed is not big problem for input of about 1 megabyte, it > becomes a problem when gigabytes are copied. > > -- > Regards, > Tomasz Rola > > -- > ** A C programmer asked whether computer had Buddha's nature. ** > ** As the answer, master did "rm -rif" on the programmer's home ** > ** directory. And then the C programmer became enlightened... ** > ** ** > ** Tomasz Rola mailto:tomasz_r...@bigfoot.com ** >
If you want to do this in C, you can also simply take advantage of the fact that read(2) takes a number of bytes as argument and stops reading at EOF: #include <stdlib.h> #include <string.h> #include <unistd.h> int main(int argc, char *argv[]) { if (argc < 2) return 1; size_t n; char *argend = argv[1] + strlen(argv[1]); if (!(n = strtoull(argv[1], &argend, 10))) return 1; char *buf = malloc(n); size_t nr = read(0, buf, n); write(1, buf, nr); free(buf); return 0; } This is probably as fast as it gets for a task this simple, and it copies as many bytes as malloc is willing to allocate.