All streams
Search
Write a publication
Pull to refresh
12
0
Алексей @RA_ZeroTech

Программист, TeamLead

Send message
К тому же, судя по коду, чтение файла происходит всего сразу. Это лишнее. И это совсем не стрим уже.

На node js у Вас должно получиться что-то вроде (условно):
FileReadStream.pipe(ParseStream).pipe(WriteStream)


где:
  • FileRead — читаем файл «кусками», а не весь сразу
  • ParseStream — обработка «кусков» по мере их чтения (у Вас это JSON)
  • WriteStream — если надо, сохраняем куда нужно результат обработки «кусков» (кэш, БД etc.)


Тогда у Вас и не будет создаваться куча объектов Promise (db.readString) в цикле

while(true) {
...
const chunk = await db.readString('\x01')
...
}
У вас сразу идёт чтение файла openSync — синхронно? Зачем?
От целей и задачи зависит. Может весь, может нет.

В любом случае, обработку (а это могут быть разные операции: чтение, парсинг строк/json etc) файлов лучше решать через Stream API NodeJs.

Возможно пригодится и Worker Threads API NodeJs (недавно появились).
Я, вроде, и не предлагал читать весь файл?


Возможно, я не так понял эту мысль:
Тут нужно сначала в один проход заполнить всеми нужными данными кэш, а потом во второй проход синхронно его обрабатывать.
А чем для этого на устраивают потоки в норде? :)
Не надо весь файл читать!
Только в выше приведённых примерах Kozack это не так.

Если, конечно, метод получения данных из кэша тоже подразумевался асинхронным.

И далее в комментариях подобные примеры приводят с вероятностью, что рано или поздно Zalgo все же вылезет :)
Вот так как раз не надо делать. Функция должна быть полностью синхронной или асинхронной.

Почитайте про “release zalgo”.
И комментарии «забавные»


// Возвращаем true, если хэш не годен, и true — если хэш годен


:)
Так и не исправили.
Прислушайтесь к рекомендациям, которые Вам тут дают.

Не пишите обучающие статьи, пока сами не разберётесь в тематике и инструментах, которые используете (упоминаете в статье).
Статья не протестирована. Есть дубли «кода» :) А именно, чем пп 1.9 отличается от пп 2.7? :)
Все должно быть в меру.
Проблема большинства, даже опытных программистов, в том, что они считают, что их имена переменным, методам, классам самые понятные для всех :) И поэтому не хотят сопровождать код комментариями вообще :)

Комментарии полезны, если они к месту.
TODO полезны, если они к месту.
FIXME полезны, если они к месту.

(с) Кэп.
Подход TDD имеет место быть. Я делюсь своим опытом. У меня пока нет понятного опыта работы с TDD, но хочу попробовать в будущем детальнее посмотреть сюда.

Понимание плюсов TDD приходит с практикой. Вы правильное делаете, что смотрите в эту сторону.

Рекомендую посмотреть для общего развития, если не видели "Зачем и как писать качественные Unit-тесты (Алексей Солодкий / Badoo)"
«Спасибо» за минусы, кто поставил :) На самом деле почитайте принцип TDD. Там как раз и говорится о том, что тест сначала, код потом. По сути, TDD говорит о том, что «вы» знаете что должен вернуть метод при определенных входящих аргументах. То есть, знаете как должен будет работать тестируемый метод. Если этого не знаете, то в общем смысле — не знаете мини-задачу, которую решаете.
Тест лучше писать до написания кода. Так больше контроля во время разработки.

Написание тестов после написания кода грозит тем, что требования теста подгоняются под готовый код. И как следствие, можно пропустить кейс с ошибкой в коде. Которая проявится потом.
пОнято :) я же не говорил, что что-то сделали не так или не правильно. Решил поинтересоваться, а что если… Вы ответили на вопрос — спасибо!
Данные в памяти в итоге могут занимать места меньше, могут так же. Потому что Вы уже их часть обработали, и отдали в АПИ или еще куда. И часть из памяти удалили… дожидаться загрузки всех данных, когда можно их уже начинать обрабатывать?

Ниже пример просто на чтение текстового файла большого объема. На основе Вашего кода:
visits_i.txt — текстовый файл около 140 Мб каждый. Простые строки каждая по 64 символа латиница

take.ms/RLGBS
duration_ts = 2.266 sec
memory usage: 153
fs.existsSync and fs.readFileSync
const fs = require('fs');

let start_ts = (new Date()).getTime();
let i = 1;
let visitsData;

function fileSync()
{
	while (fs.existsSync(`./visits_${i}.txt`) && (visitsData = fs.readFileSync(`./visits_${i}.txt`, 'utf8')))
	{
		//...
		console.log({
			'file': `./visits_${i}.txt`,
			'visitsData': visitsData.length
		});
		i++;
	}
}
fileSync();

let end_ts = (new Date()).getTime();
let diffMts = end_ts - start_ts;
let duration_ts = diffMts/1000;
console.log(`duration_ts = ${duration_ts} sec`);

global.gc();
console.log("memory usage: " + parseInt(process.memoryUsage().heapTotal/1000000));



take.ms/km7CT

duration_ts = 2.318 sec — а бывало и меньше ( = 1.99 sec)
memory usage: 11
fs.stat & fs.readFile
const fs = require('fs');
let start_ts = (new Date()).getTime();
let i = 1;
let visitsData;
//fs.exists - is Deprecated
function fileAsync(i)
{
	let path = `./visits_${i}.txt`;
	fs.stat(path, (err, stats)=>
	{
		if (err) //когда i++ файла не будет найдено 
		{
			let end_ts = (new Date()).getTime();
			let diffMts = end_ts - start_ts;
			let duration_ts = diffMts/1000;
			console.log(`duration_ts = ${duration_ts} sec`);
			global.gc();
			console.log("memory usage: " + parseInt(process.memoryUsage().heapTotal/1000000));
			return;
		}
		fs.readFile(path, {encoding: 'utf8'}, (err, visitsData) =>
		{
			if (err) throw err;
			
			//TODO parse visitsData
			console.log({
				'file': path,
				'visitsData': visitsData.length
			});
			i++;
			return fileAsync(i);
		});
	});
}
fileAsync(i);



take.ms/UcgL9
duration_ts = 1.167 sec
memory usage: 12
fs.createReadStream
const fs = require('fs');

let start_ts = (new Date()).getTime();
let i = 1;
let data;
function streamFile(i)
{
	let path = `./visits_${i}.txt`;
	const RS = fs.createReadStream(path);
	console.log('path = ', path);
	RS.on('data', (data)=>
	{
		//TODO parse data
	});
	RS.on('end', () =>
	{
		if (i >= 10)
		{
			let end_ts = (new Date()).getTime();
			let diffMts = end_ts - start_ts;
			let duration_ts = diffMts/1000;
			
			console.log(`duration_ts = ${duration_ts} sec`);
			global.gc();
			console.log("memory usage: " + parseInt(process.memoryUsage().heapTotal/1000000));
		}
		else
		{
			i++;
			return streamFile(i);
		}
	});
}
streamFile(i);



Вроде условия вывода memoryUsage поставил в правильном месте? По окончании чтения всех файлов.
для версии на Node не пробовали использовать асинхронные версии методов чтения файлов?
и/или потоки?
BimBam, Вы автор перевода? Просьба. Перечитайте текст, и перепишите некоторый предложения с «русского языка» на русский язык. И знаки препинания не забывайте… Вроде понимаешь при чтении о чем написано, но приходится перечитывать, чтобы убедиться…

Это объединяет наших специалистов в одну команду которая позволяет нам понимать и реагировать на потребности пользователей на любом из уровней наших технологий.


… мы скоро будем открывать его исходный код!...


И далее по тексту еще есть подобное.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Registered
Activity