Amit's answer is super helpful, thanks for that. But there is one major error:
$diff = array_diff($new_value, $old_value);
PHP's array_diff will only tell you about values that are in the first param that are not in the second param. So, if we are updating a node and we delete (instead of add) a new value i na field, array_diff will not notice this and the node will not be marked by this code as changed (assuming that is the only change).
Instead, that line should be changed to:
$diff = array_merge(array_diff($new_value, $old_value), array_diff($old_value, $new_value));
I tested this locally, successfully.
I picked up that array_merge tidbit from https://stackoverflow.com/questions/10077840/difference-between-two-arrays
I don't have enough rep to comment on the post, but I can edit it, subject to moderation, so I will do that.