Ответ 1
Наблюдение за байт-кодом помогло мне ответить на этот вопрос. Байт-код для рабочей части первого script:
10 58 SETUP_LOOP 27 (to 88)
61 LOAD_NAME 3 (sys)
64 LOAD_ATTR 6 (stdin)
67 GET_ITER
>> 68 FOR_ITER 16 (to 87)
71 STORE_NAME 7 (line)
11 74 LOAD_NAME 4 (count)
77 LOAD_CONST 4 (1)
80 INPLACE_ADD
81 STORE_NAME 4 (count)
84 JUMP_ABSOLUTE 68
>> 87 POP_BLOCK
И байт-код для соответствующей части второго script:
12 18 SETUP_LOOP 24 (to 45)
21 LOAD_FAST 0 (input)
24 GET_ITER
>> 25 FOR_ITER 16 (to 44)
28 STORE_FAST 3 (line)
13 31 LOAD_FAST 1 (count)
34 LOAD_CONST 2 (1)
37 INPLACE_ADD
38 STORE_FAST 1 (count)
41 JUMP_ABSOLUTE 25
>> 44 POP_BLOCK
Я вижу, что фактическая разница между этими кодами заключается в использовании LOAD_NAME против LOAD_FAST и STORE_NAME против STORE_FAST. Документация http://docs.python.org/2.7/library/dis.html#opcode-LOAD_FAST гласит, что LOAD_FAST выполняет поиск с использованием только индексов, в то время как LOAD_NAME ищет переменную по имени строки. И первый подход в два раза быстрее.