Мне нужно создать CSV-файл 50 миллионов строк со случайными данными: как оптимизировать эту программу?
Программа ниже может генерировать случайные данные в соответствии с некоторыми спецификациями (пример здесь для 2 столбцов)
Он работает с несколькими сотнями тысяч строк на моем ПК (должно зависеть от оперативной памяти). Мне нужно масштабировать до десятка миллионов строк.
Как я могу оптимизировать программу для записи прямо на диск? С другой стороны, как я могу "кэшировать" выполнение правила синтаксического анализа, поскольку это всегда один и тот же шаблон, повторяемый 50 миллионов раз?
Примечание: чтобы использовать программу ниже, просто введите generate-blocks, и выходные данные save-blocks будут db.txt
Rebol[]
specs: [
[3 digits 4 digits 4 letters]
[2 letters 2 digits]
]
;====================================================================================================================
digits: charset "0123456789"
letters: charset "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
separator: charset ";"
block-letters: [A B C D E F G H I J K L M N O P Q R S T U V W X Y Z]
blocks: copy []
generate-row: func[][
Foreach spec specs [
rule: [
any [
[
set times integer! [['digits (
repeat n times [
block: rejoin [block random 9]
]
)
|
'letters (repeat n times [
block: rejoin [ block to-string pick block-letters random 24]
]
)
]
|
[
'letters (repeat n times [block: rejoin [ block to-string pick block-letters random 24]
]
)
|
'digits (repeat n times [block: rejoin [block random 9]]
)
]
]
|
{"} any separator {"}
]
]
to end
]
block: copy ""
parse spec rule
append blocks block
]
]
generate-blocks: func[m][
repeat num m [
generate-row
]
]
quote: func[string][
rejoin [{"} string {"}]
]
save-blocks: func[file][
if exists? to-rebol-file file [
answer: ask rejoin ["delete " file "? (Y/N): "]
if (answer = "Y") [
delete %db.txt
]
]
foreach [field1 field2] blocks [
write/lines/append %db.txt rejoin [quote field1 ";" quote field2]
]
]
1 ответ
Используйте open with /direct и /lines уточнение для прямой записи в файл без буферизации содержимого:
file: open/direct/lines/write %myfile.txt
loop 1000 [
t: random "abcdefghi"
append file t
]
Close file
Это напишет 1000 случайных строк без буферизации. Вы также можете подготовить блок строк (скажем, 10000 строк), а затем записать его непосредственно в файл, это будет быстрее, чем запись построчно.
file: open/direct/lines/write %myfile.txt
loop 100 [
b: copy []
loop 1000 [append b random "abcdef"]
append file b
]
close file
это будет намного быстрее, 100000 строк меньше секунды. Надеюсь, это поможет.
Обратите внимание, что вы можете изменить число 100 и 1000 в зависимости от ваших потребностей в памяти вашего компьютера и использовать b: make block! 1000 вместо b: copy [], это будет быстрее.