Как читать большой json?
Я получаю json файлы с данными для анализа в R, для которых я использую RJSONIO-пакет:
library(RJSONIO)
filename <- "Indata.json"
jFile <- fromJSON(filename)
Когда json файлы больше 300 МБ (несжатые), мой компьютер начинает использовать память подкачки и продолжает синтаксический анализ (fromJSON) в течение нескольких часов. 200MB файл занимает всего около минуты для разбора.
Я использую R 2.14 (64 бит) на 64-битной Ubuntu с 16 ГБ оперативной памяти, поэтому я удивлен, что замена требуется уже около 300 МБ json.
Что я могу сделать, чтобы читать большие jsons? Есть ли что-то в настройках памяти, которые все испортили? Я перезапустил R и запустил только три строки выше. Json файл содержит 2-3 столбца с короткими строками и 10-20 столбцов с номерами от 0 до 1000000. I.e. это число строк, которое делает большой размер (более миллиона строк в анализируемых данных).
Обновление: Из комментариев я узнал, что rjson сделан больше на C, поэтому я попробовал. 300 МБ файл, который с RJSONIO (согласно Ubuntu System Monitor) достиг 100% -ной памяти (с 6% базовой линии) и продолжал замену, нуждался только в 60% -ной памяти с пакетом rjson, и разбор проводился в разумные сроки (минуты).
Ответы
Ответ 1
Хотя ваш вопрос не определяет эту деталь, вы можете захотеть убедиться, что загрузка всего JSON в память на самом деле вам нужна. Похоже, RJSONIO - это API на основе DOM.
Какое вычисление вам нужно сделать? Можете ли вы использовать потоковой парсер? Примером SAX-подобного потокового анализатора для JSON является yajl.
Ответ 2
Даже если вопрос очень старый, это может быть полезно для кого-то с аналогичной проблемой.
Функция jsonlite::stream_in()
позволяет определить pagesize
, чтобы установить количество строк, считанных за раз, и настраиваемая функция, применяемая к этому подмножеству на каждой итерации, может быть предоставлена как handler
. Это позволяет работать с очень большими JSON файлами, не одновременно считывая все в память.
stream_in(con, pagesize = 5000, handler = function(x){
# Do something with the data here
})
Ответ 3
Не для размера памяти, а для скорости, для довольно небольшого набора данных iris
(всего 7088 байт) пакет RJSONIO
на порядок медленнее, чем rjson
. Не используйте метод "R", если вам действительно не нужно! Обратите внимание на разные единицы в двух наборах результатов.
library(rjson) # library(RJSONIO)
library(plyr)
library(microbenchmark)
x <- toJSON(iris)
(op <- microbenchmark(CJ=toJSON(iris), RJ=toJSON(iris, method='R'),
JC=fromJSON(x), JR=fromJSON(x, method='R') ) )
# for rjson on this machine...
Unit: microseconds
expr min lq median uq max
1 CJ 491.470 496.5215 501.467 537.6295 561.437
2 JC 242.079 249.8860 259.562 274.5550 325.885
3 JR 167673.237 170963.4895 171784.270 172132.7540 190310.582
4 RJ 912.666 925.3390 957.250 1014.2075 1153.494
# for RJSONIO on the same machine...
Unit: milliseconds
expr min lq median uq max
1 CJ 7.338376 7.467097 7.563563 7.639456 8.591748
2 JC 1.186369 1.234235 1.247235 1.265922 2.165260
3 JR 1.196690 1.238406 1.259552 1.278455 2.325789
4 RJ 7.353977 7.481313 7.586960 7.947347 9.364393