You should read part 3 of the article cited in the answer you linked.
In part 3, you can see that the problem is not only when using Python native types, but also when using Python constructs (like for) that operate on Python types and not on tf.Tensor objects.
In particular, when looping over a range and not on a tf.range you're building a huge graph since you're repeating 1000 times the body loop (you're unrolling the loop.
If you replace range with tf.range everything goes way faster.
Proof.
Your code (with time measurements and 100 instead of 1000):
import numpy as np
import tensorflow as tf
from time import time
@tf.function
def loop(x, y):
for i in range(100):
x.assign_add(y)
return x
@tf.function
def loop2(x, y):
for i in range(100):
loop(x, y)
return x
def main():
print("TensorFlow version: {}".format(tf.__version__))
print("Eager execution: {}".format(tf.executing_eagerly()))
x = tf.Variable(initial_value=0, dtype=np.float32)
y = tf.Variable(initial_value=1, dtype=np.float32)
print("one")
start = time()
print(loop2(x, y)) # horribly slow
print("end: ", time() - start)
print("second: ")
start = time()
for i in range(100): # faster
loop(x, y)
print("end: ", time() - start)
main()
The output:
TensorFlow version: 2.0.0-beta0
Eager execution: True
one
tf.Tensor(10000.0, shape=(), dtype=float32)
end: 86.44128751754761
second:
end: 0.08476066589355469
Updated code using only TensorFlow methods:
@tf.function
def loop__(x, y):
for i in tf.range(100):
x.assign_add(y)
return x
@tf.function
def loop2__(x, y):
for i in tf.range(100):
loop__(x, y)
return x
def main():
print("TensorFlow version: {}".format(tf.__version__))
print("Eager execution: {}".format(tf.executing_eagerly()))
x = tf.Variable(initial_value=0, dtype=np.float32)
y = tf.Variable(initial_value=1, dtype=np.float32)
print("one")
start = time()
print(loop2__(x, y)) # horribly slow
print("end: ", time() - start)
print("second: ")
start = time()
for i in tf.range(100): # faster
loop__(x, y)
print("end: ", time() - start)
main()
The output:
TensorFlow version: 2.0.0-beta0
Eager execution: True
one
tf.Tensor(10000.0, shape=(), dtype=float32)
end: 0.4946322441101074
second:
end: 0.24096465110778809