I don't think Salesforce offer much official documentation on CPU and heap consumption.
On the CPU time, bear in mind that the time taken to do a fixed amount of processing will vary from request to request. (See e.g. How does SF calculate the CPU time? for lots of background on that.) And that in the future you or someone else might add additional logic (such as a validation rule) that will consume more CPU time. It is not possible to exactly predict CPU time consumption and so the pragmatic approach is to experiment and measure (as you are doing) and pick a conservative number of records as the limit to ensure you are a long way away from hitting the 10 second limit.
You should probably also review your code for code patterns that consume a lot of CPU time needlessly - see e.g. Fixing a common cause of System.LimitException: Apex CPU time limit exceeded. Its easy to add code where the performance degrades exponentially.
Apex is a garbage collected language so heap is consumed when your code holds on to references to objects. The size of each object can be anything from a few bytes to multiple megabytes. To hold down heap consumption don't hold large collections of large objects. One Apex mechanism to help with that when querying is SOQL For Loops.
Heap doesn't look like a problem for your example, but if it was review the code to ensure references are only kept when needed and that references to large objects such as Blobs or SObjects with many large fields or large strings are not being kept. Then similarly to the CPU case, experiment and pick a conservative number of records to stay a long way away from hitting the 6M limit.
Dividing the work up into multiple pieces (where each piece gets its own set of governor limits) by using the Batch Apex mechanism is another option to consider.