Я пытаюсь сравнить два разных способа обработки файла. У меня есть небольшое количество входных данных, но чтобы получить хорошее сравнение, мне нужно повторить тесты несколько раз.
Вместо того, чтобы просто повторять тесты, я хотел бы дублировать входные данные несколько раз (например, 1000), чтобы 3-строчный файл превратился в 3000 строк, и я могу выполнить гораздо более эффективный тест.
Я передаю входные данные через имя файла:
mycommand input-data.txt
perl
он настолько эффективен, что предназначен для этого.Первоначально я думал, что мне нужно будет создать вторичный файл, но я мог бы просто зациклить исходный файл в Bash и использовать некоторое перенаправление, чтобы он выглядел как файл.
Существует, вероятно, дюжина различных способов сделать цикл, но вот четыре:
Третий метод импровизирован из комментария Мару ниже и создает большой список имен входных файлов для cat.
xargs
разделит это на столько аргументов, сколько позволит система. Это гораздо быстрее , чем п отдельных кошек.awk
Способ (вдохновленный ответ terdon в ), вероятно, наиболее оптимизирован , но он дублирует каждую строку в то время. Это может или не может удовлетворить конкретное применение, но это молниеносно и эффективно.Но это генерируется на лету. Вывод Bash, скорее всего, будет намного медленнее, чем что-либо может прочитать, поэтому вы должны сгенерировать новый файл для тестирования. К счастью, это очень простое расширение:
источник
cat $(for i in {1..N}; do echo filename; done)
. Это имеет ограничение размера arg, но должно быть быстрее.Вот
awk
решение:По сути это так же быстро, как Perl @ Gnuc (я бегал 1000 раз и получил среднее время):
источник
awk '{for(i=0; i<1000; i++)print}' input-data.txt
такого, чтобы он просто выдавал 1000 копий каждой строки за раз. Не подходит для всех случаев, но даже быстрее, с меньшей задержкой и не требует хранения всего файла в оперативной памяти.123123123
было хорошо, но111222333
это не так. Ваша версия явно быстрее, чем у Gnouc, в среднем она составляет 0,00297 секунды. РЕДАКТИРОВАТЬ: поцарапать это, я сделал ошибку, это на самом деле эквивалентно в 0,004013 секунд.Я бы просто использовал текстовый редактор.
Если вы абсолютно необходимо сделать это с помощью командной строки (это требует , чтобы вы были
vim
установлена, посколькуvi
не имеет:normal
команды), вы можете использовать:Здесь
-es
(или-e -s
) заставляет vim работать тихо, поэтому он не должен захватывать окно вашего терминала и-u NONE
не дает ему смотреть на ваш vimrc, что должно заставить его работать немного быстрее, чем в противном случае (возможно, намного быстрее, если вы используете много плагинов vim).источник
Вот простая однострочная, без сценариев:
объяснение
`yes input-data.txt | head -1000 | paste -s`
выдает текстinput-data.txt
1000 раз, разделенный пробеломcat
в виде списка файловисточник
xargs paste -s
? Это работает, но не сохраняет переносы во входном файле.Работая над совершенно другим сценарием, я узнал, что с 29 миллионами строк текста использование
seek()
и работа с данными побайтно часто быстрее, чем построчно. Та же идея применяется в приведенном ниже сценарии: мы открываем файл, и вместо того, чтобы циклически открывать и закрывать файл (что может привести к дополнительным расходам, даже если это не важно), мы сохраняем файл открытым и возвращаемся к началу.Сам скрипт довольно прост в использовании:
Для 3-строчного текстового файла и 1000 итераций все идет хорошо, около 0,1 секунды:
Сам сценарий не самый элегантный, вероятно, может быть сокращен, но выполняет свою работу. Конечно, я добавил кое-что еще, например,
error_out()
функцию, которая не нужна - это всего лишь небольшое удобное касание.источник
Мы можем решить это без дополнительного файла, без специальных программ, чистого Bash (ну, cat - стандартная команда).
Основываясь на функции printf внутри bash, мы можем сгенерировать повторяющуюся строку):
Затем мы можем отправить такой список из 1000 имен файлов (повторяется) и вызвать cat:
И, наконец, мы можем дать вывод команде для выполнения:
Или, если команда должна получить вход в стандартный ввод:
Да, двойной <необходим.
источник
Я бы сгенерировал новый файл, используя Unix для цикла:
источник