Hacker News new | ask | show | jobs
by sumtechguy 46 days ago
Also you need to be careful what you read/write. In some cases.

As many examples out there use int/char etc to show how to use the thing. But if you switch to structs that fwrite can totally burn you if you use the sizeof call. As the sizeof a struct can vary between platforms and compilers. Depending on packing. Then endianness can sometimes mess you up. If you are reading/writing for yourself you can get away with a lot. But if you are trying to interop then you have to be wildly careful what you do.

fwrite is another one where people will do one byte at a time (same up to for the windows version). Bash out a loop, use the sizeof for the input to the for loop. copy and paste just doing 1 byte and you can easily end up here. One program I added a cache in front of the thing so it would always write on disk block boundaries and then come back for more. I started off with just packed struct sizes but the perf was just 'ok'. The file block boundary thing really made it fast. Not all OS's have a readahead/write buffer behind that call so perf can vary.

It is honestly such an easy mistake to make. As many of the examples/docs do not really show you why/how to use both of those calls in the way needed. You sort of have to stumble into it and work it out.

Once you see it you know. But until then you do not really notice if it is 'working'.

1 comments

Are you sure you're not thinking of raw read() / write() (the operating systems calls) rather than fread() and fwrite() (the C standard library functions)? fread and fwrite already have a cache, so repeated calls won't make lots of OS calls.

Or, at least, they shouldn't! Clearly OP's implementation was a counterexample (it made lots of OS calls just for a single fread call).

Unfortunately not all of them. It depends on the device you are using, and the storage device, and the kernel, and the CRT you are using. The process I was using went from like 20-30 seconds to run to less than a second once I put a cache in front of it. Current implementations may have that cache. I would look first and see what they are doing. At the time I was working with about 6 different CRT's of varying age and quality. Some systems you can turn it on and off per device, or global, or per call depending on flags passed in. Really it comes down to reading the docs (probably right), and testing it out (empirical evnidence). That project I learned to not trust the c runtime libraries. But to verify what they are doing and re-read the docs and make sure I am even using the thing correctly vs what is written in the code and my assumptions.