Это может быть быстрее вашего. Не делает предположений о длине строки. Запускается через файл по одному блоку за раз, пока не будет найдено правильное количество символов «\n».
def tail( f, lines=20 ):
total_lines_wanted = lines
BLOCK_SIZE = 1024
f.seek(0, 2)
block_end_byte = f.tell()
lines_to_go = total_lines_wanted
block_number = -1
blocks = [] # blocks of size BLOCK_SIZE, in reverse order starting
# from the end of the file
while lines_to_go > 0 and block_end_byte > 0:
if (block_end_byte - BLOCK_SIZE > 0):
# read the last block we haven't yet read
f.seek(block_number*BLOCK_SIZE, 2)
blocks.append(f.read(BLOCK_SIZE))
else:
# file too small, start from begining
f.seek(0,0)
# only read what was not read
blocks.append(f.read(block_end_byte))
lines_found = blocks[-1].count('\n')
lines_to_go -= lines_found
block_end_byte -= BLOCK_SIZE
block_number -= 1
all_read_text = ''.join(reversed(blocks))
return '\n'.join(all_read_text.splitlines()[-total_lines_wanted:])
Мне не нравятся сложные предположения о длине строки, когда - в практическом плане - - вы никогда не можете знать такие вещи.
Как правило, это будет определять последние 20 строк на первом или втором проходе через цикл. Если ваша 74-значная вещь на самом деле точна, вы делаете размер блока 2048, и вы почти сразу получите 20 строк.
Кроме того, я не сжигаю много мозговых калорий, пытаясь выровнять выравнивание с физическими Блоки ОС. Используя эти высокоуровневые пакеты ввода-вывода, я сомневаюсь, что вы увидите какое-либо влияние производительности на попытку выравнивания по границам блоков ОС. Если вы используете ввод-вывод нижнего уровня, вы можете увидеть ускорение.
Если вы переместите линию
Vue.prototype.$hi = () => alert('hi');
выше
let component = new TestComponent().$mount(wrapper)
, она будет работать. Ваш первый компонент ссылается на $hi()
до его определения.