Ответ 1
(Это ответ на код, который теперь был отредактирован из исходного вопроса). Вы забыли вызвать функции во втором случае. Делая соответствующие модификации, результаты ожидаемые:
test1 = """
def foo1():
     my_set1 = set((1, 2, 3))
foo1()
"""    
timeit(test1)
# 0.48808742000255734
test2 = """
def foo2():
    my_set2 = {1,2,3}
foo2()
"""    
timeit(test2)
# 0.3064506609807722
 Теперь причина разницы во времени заключается в том, что set() - это вызов функции, требующий поиска в таблице символов, тогда как конструкция набора {...} является артефактом синтаксиса и намного быстрее.
Разница очевидна при просмотре разобранного байтового кода.
import dis
dis.dis("set((1, 2, 3))")
  1           0 LOAD_NAME                0 (set)
              2 LOAD_CONST               3 ((1, 2, 3))
              4 CALL_FUNCTION            1
              6 RETURN_VALUE
dis.dis("{1, 2, 3}")
  1           0 LOAD_CONST               0 (1)
              2 LOAD_CONST               1 (2)
              4 LOAD_CONST               2 (3)
              6 BUILD_SET                3
              8 RETURN_VALUE
 В первом случае вызов функции выполняется инструкцией CALL_FUNCTION для кортежа (1, 2, 3) (которая также имеет свои собственные издержки, хотя и незначительные - она загружается как константа через LOAD_CONST), тогда как во втором инструкция - это просто вызов BUILD_SET, который более эффективен.
Re: ваш вопрос относительно времени, необходимого для построения кортежа, мы видим, что это на самом деле незначительно:
timeit("""(1, 2, 3)""")
# 0.01858693000394851
timeit("""{1, 2, 3}""")
# 0.11971827200613916
 Кортежи являются неизменяемыми, поэтому компилятор оптимизирует эту операцию, загружая ее как константу - это называется постоянным свертыванием (вы можете ясно увидеть это из инструкции LOAD_CONST выше), поэтому время, затрачиваемое на это, незначительно. С наборами это не видно, поскольку они изменчивы (спасибо @user2357112 за указание на это).
 Для больших последовательностей мы видим похожее поведение. Синтаксис {..} работает быстрее при построении множеств с использованием определений множеств, в отличие от set() который должен строить множество из генератора.
timeit("""set(i for i in range(10000))""", number=1000)
# 0.9775058150407858
timeit("""{i for i in range(10000)}""", number=1000)
# 0.5508635920123197
Для справки, вы также можете использовать повторяемую распаковку на более поздних версиях:
timeit("""{*range(10000)}""", number=1000)
# 0.7462548640323803
 Интересно, однако, что set() быстрее, когда вызывается непосредственно в range:
timeit("""set(range(10000))""", number=1000)
# 0.3746800610097125
 Это происходит быстрее, чем заданная конструкция. Вы увидите похожее поведение для других последовательностей (таких как list s).
 Моя рекомендация заключается в использовании {...} понимания набора при создании литералов набора и в качестве альтернативы передаче понимания генератора функции set(); и вместо этого используйте set() для преобразования существующей последовательности/итерируемой в набор.
