使用Node.js,我有一个任务来改进我创建的代码。此代码执行60个HTTP请求,并为此使用库。
完成所有HTTP请求并将每个请求保存到一个文件需要30秒!
据说,可以在3秒内完成这些请求,包括:
1.正确管理异步承诺
2.更智能的缓存
3.不使用集群
4.只增加一次的开销
恐怕我不知道从哪里开始,明白我能做些什么。
因此,下面的代码获得了一个由60个项组成的数组,其中每个条目都是一个HTTP请求:
const exchanges = ccxt.exchanges
这些内容进入: worker =异步函数,在代码结束时:等待Promise.all(工人)等待他们完成。
,我不知道从哪里开始,实际上可以降到3秒。如何才能提高代码的速度?
'use strict';
const ccxt = require ('ccxt')
, log = require ('ololog').noLocate // npm install ololog
, fs = require ('fs')
// the numWorkers constant defines the number of concurrent workers
// those aren't really threads in terms of the async environment
// set this to the number of cores in your CPU * 2
// or play with this number to find a setting that works best for you
, numWorkers = 8
;(async () => {
// make an array of all exchanges
const exchanges = ccxt.exchanges
.filter (id => ![ 'cap1', 'cap2' ].includes (id))
// instantiate each exchange and save it to the exchanges list
.map (id => new ccxt[id] ({
'enableRateLimit': true,
}))
// the worker function for each "async thread"
const worker = async function () {
// while the array of all exchanges is not empty
while (exchanges.length > 0) {
// pop one exchange from the array
const exchange = exchanges.pop()
// check if it has the necessary method implemented
if (exchange.has['fetchTickers']) {
// try to do "the work" and handle errors if any
try {
// fetch the response for all tickers from the exchange
const tickers = await exchange.fetchTickers()
// make a filename from exchange id
const filename = '/myproject/tickers/' + exchange.id + 'Tickers.json'
// save the response to a file
fs.writeFileSync(filename, JSON.stringify({ tickers }));
} catch (e) { } //Error
}
}
}
// create numWorkers "threads" (they aren't really threads)
const workers = [ ... Array (numWorkers) ].map (_ => worker ())
// wait for all of them to execute or fail
await Promise.all (workers)
}) ()
发布于 2019-02-22 00:29:33
我觉得你把事情弄得比他们需要的复杂多了。您可以在map回调中完成所有工作,然后使用Promise.all(promises)等待所有操作完成。这个过程确实比预期的“3秒”更长(在我的例子中是15秒),并且产生了很多错误(比如缺少apiToken,或者fetchTickers没有实现),但是这可能是我的环境中的一个问题(我以前从未使用过ccxt,也没有任何apiTokens)。
这是我想出的实现,希望它能帮助您满足您的需求:
const ccxt = require('ccxt');
const fs = require('fs');
const path = require('path');
(async () => {
const start = Date.now();
const dumps = ccxt.exchanges
.filter((id) => !['coinmarketcap', 'theocean'].includes(id))
.map(async (id) => {
const Exchange = ccxt[id];
const exchange = new Exchange({enableRateLimit: true});
if (exchange.has['fetchTickers']) {
try {
const tickers = await exchange.fetchTickers();
const dumpFile = path.join(__dirname, 'exchanges', `${id}-Tickers.json`);
await fs.promises.writeFile(dumpFile, JSON.stringify(tickers));
} catch (e) {
console.error(e);
}
}
});
await Promise.all(dumps);
const end = Date.now();
console.log(`Done in ${(end - start) / 1000} seconds`);
})();发布于 2019-02-21 23:14:02
我试着看看是否有可能更快地做到这一点。我试着把所有可能需要的记忆藏起来。在实际执行.fetchTickers()请求之前。
我从看上去的15秒下降到了9秒。但是下面的代码甚至还有一步,但是我确实收到了编译错误,并且不确定我做错了什么。
错误是:
ReferenceError: id未定义
难道id不是在“.pushed”的“exchange”对象中传递到“exchangesArray”中吗?
我试图首先将exchange对象放入数组中,所需时间如下:
var exchangesArray = [];
然后,在设置了这个"exchangesArray“之后,我尝试执行执行fetchTickers的函数:
'use strict';
const ccxt = require('ccxt');
const fs = require('fs');
const path = require('path');
//Cache some memories first
var exchangesArray = [];
(async () => {
const allexchanges = ccxt.exchanges.filter((id) => !['coinmarketcap', 'theocean'].includes(id))
.map(async (id) => {
const Exchange = ccxt[id];
const exchange = new Exchange({ enableRateLimit: true });
if (exchange.has['fetchTickers']) {
exchangesArray.push(exchange);
}
});
await Promise.all(allexchanges);
})();
//Use cached memories to do the "fetchTickers()" as fast as possible
(async () => {
const start = Date.now();
const exchanges = exchangesArray;
while (exchanges.length > 0) {
// pop one exchange from the array
const exchange = exchanges.pop()
try {
const tickers = await exchange.fetchTickers();
const dumpFile = path.join(__dirname, 'exchanges', `${id}-Tickers.json`);
await fs.promises.writeFile(dumpFile, JSON.stringify(tickers));
} catch (e) {
console.error(e);
}
}
await Promise.all(exchanges);
const end = Date.now();
console.log(`Done in ${(end - start) / 1000} seconds`);
})();
https://stackoverflow.com/questions/54816672
复制相似问题