Silly question: what counts as a "unit of work" when computing big-Oh time complexity I am going through a fairly non-rigorous textbook called 'Cracking the code interview' and I am bothered by this terminology called &quot;unit of work&quot;.
It says in the textbook that certain operations take constant work, where as others take variable amount of time.
For example, adding/subtracting/multiplying/dividing two numbers take constant work. Similarly, a comparison statement also takes constant work. Lookup are also constant.
Whereas other operations such as for-loop takes a variable amount of work. For example, if a FOR-loop is to be run from $i = 0$ to $i = n-1$, and assuming whatever inside of the FOR-loop takes constant amount of time, then the total amount of work is proportional to $n$. That is, FOR-loop takes $O(n)$ time.
Something that doesn't really make sense to me is the smallest unit that can be defined as &quot;work&quot; in big Oh runtime analysis. What is this unit based off of? Adding two bits together? Adding two integers together?
Stemming from it are two related concerns:

certainly multiplication takes more &quot;work&quot; than addition. Division takes more work than subtraction. So what is the smallest unit of work here? Is the time to add two numbers a smaller amount of work than multiplying two numbers? That is, is the work of multiplication proportional to the time of addition?, $\text{work}_{\times} = c \times  \text{work}_{+}, c &gt; 0?$

For example, are things like multiplication truly independent of the input? $k \times n = n + n + \ldots + n$ ($k$ times). So why is it considered a constant amount of work? Doesn't the same logic also apply to other programs? Say if I have $n$ conditional statement checking if a value is smaller or greater than a number $n$. Then this &quot;constant&quot; operation can still depend on how large my $n$ is (depending on how i implement this comparison).


Thanks for your patience.
We assume an efficient implementation of standard arithmetic operations (since a stupid implementation could be replaced with a better one). Of course, if the numbers were of unlimited size, the amount of time wouldn't be constant. But it would still be constant per bit (at least for addition and comparison).
So if we pretend that all numbers are a constant size (&quot;one unit of storage&quot;) and we pretend that all additions are constant time (&quot;one unit of work&quot;), we get the same relationship between input size and processing time as we would if we worked it out measuring space in bits and processing time in single-bit operations: time is linear in input size.
Complexity analysis is not about nanoseconds. You can't figure out how many nanoseconds an algorithm will take just by looking at the algorithm. What we can figure out is what happens to the time if you increase the problem size. Twice as long is twice as long regardless of what the measurement unit is. The measurement unit is irrelevant as long as we use the same one throughout.
Now, if we were really doing arbitrary precision arithmetic, multiplication and division would take polynomial time. But for most algorithms, taking that into account would massively complicate the analysis without adding much new information. So it's convenient to pretend multiplication and division are linear time.