I think your timing might give weird results, because your synchronization points are different in both implementations.
Calling .item() on a tensor gives you a standard Python number, which is pushed to the CPU.
This line of code would add a synchronization to wait for the GPU to finish calculating.
I’m not completely sure, if that’s also the case calling .data[0] without e.g. a print statement or if the operation can run asynchronously.
If you would like to time certain operations, you should call torch.cuda.synchronize() before stopping the timer.
This could make your overall script slower, but will yield valid timing results.