docs: performance best practices

This commit is contained in:
ppedziwiatr
2022-01-03 13:43:21 +01:00
committed by Piotr Pędziwiatr
parent b467ef6881
commit ade2d6ff6a
6 changed files with 54 additions and 11022 deletions

View File

@@ -16,6 +16,7 @@ To further improve contract state evaluation time, one can additionally use AWS
- [Development](#development)
- [Installation and import](#installation-and-import)
- [Using the RedStone Gateway](#using-the-redstone-gateway)
- [Performance - best practices](#performance---best-practices)
- [Examples](#examples)
- [Migration guide](#migration-guide)
- [Documentation](#documentation)
@@ -114,6 +115,46 @@ const smartweave = SmartWeaveNodeFactory.memCachedBased(arweave)
More examples can be found [here](https://github.com/redstone-finance/redstone-smartcontracts-examples/blob/main/src/redstone-gateway-example.ts).
### Performance - best practices
In order to get the best performance on production environment (or while performing benchmarks ;-)), please follow these simple rules:
1. Do NOT use the `TsLoggerFactory` - it is good for development, as it formats the logs nicely, but might slow down the state evaluation
by a factor of 2 or 3 (depending on the logging level).
2. Use `fatal` or `error` log level, e.g.:
```ts
// configure the logging first
LoggerFactory.INST.logLevel("fatal");
// or
LoggerFactory.INST.logLevel("error");
// then create an instance of smartweave sdk
const smartweave = SmartWeaveWebFactory.memCached(arweave);
```
Logging on `info` or `debug` level is good for development, but turning it on globally might slow down the evaluation by a factor of 2.
Keep in mind that you can fine tune the log level of each module separately. For example you can switch the `fatal` globally, but `debug`
for the `ArweaveGatewayInteractionsLoader` (in order to verify the load times from Arweave GQL endpoint). The names of the modules are derived from the
names of TypeScript classes, e.g.:
```ts
// configure the logging first
LoggerFactory.INST.logLevel("fatal");
LoggerFactory.INST.logLevel("debug", "ArweaveGatewayInteractionsLoader");
// then create an instance of smartweave sdk
const smartweave = SmartWeaveWebFactory.memCached(arweave);
```
3. If your contract does not make any `readContractState` calls (i.e. it is not reading other contracts' state), you can switch the
`updateCacheForEachInteraction` flag to `false` - this will limit the amounts of writes to the state cache (and therefore decrease the execution time for such contracts), e.g.:
```ts
// create an instance of smartweave sdk
const smartweave = SmartWeaveWebFactory.memCached(arweave);
// then connect it to a given contract with "updateCacheForEachInteraction" set to "false"
const contract = smartweave.contract(contractTxId).setEvaluationOptions({
updateCacheForEachInteraction: false
});
```
### Examples
Usage examples can be found in
a dedicated [repository](https://github.com/redstone-finance/redstone-smartcontracts-examples).

View File

@@ -63,8 +63,6 @@ export class MemBlockHeightSwCache<V = any> implements BlockHeightSwCache<V> {
cached.delete(toRemove);
}
// note: "value" should be deep copied here for safety
// but it significantly degrades overall performance...
cached.set(blockHeight, value);
}

View File

@@ -115,9 +115,12 @@ export class HandlerBasedContract<State> implements Contract<State> {
const result = await stateEvaluator.eval(executionContext, currentTx || []);
stateBenchmark.stop();
const total = (initBenchmark.elapsed(true) as number) + (stateBenchmark.elapsed(true) as number);
this.logger.info('Benchmark', {
'init time': initBenchmark.elapsed(),
'evaluation time': stateBenchmark.elapsed()
'Gateway communication ': initBenchmark.elapsed(),
'Contract evaluation ': stateBenchmark.elapsed(),
'Total: ': `${total.toFixed(0)}ms`
});
return result as EvalStateResult<State>;
}

View File

@@ -36,8 +36,8 @@ async function main() {
logging: false // Enable network request logging
});
//const contractTxId = 'Daj-MNSnH55TDfxqC7v4eq0lKzVIwh98srUaWqyuZtY';
const contractTxId = 't9T7DIOGxx4VWXoCEeYYarFYeERTpWIC1V3y-BPZgKE'; //749180
const contractTxId = 'Daj-MNSnH55TDfxqC7v4eq0lKzVIwh98srUaWqyuZtY';
//const contractTxId = 't9T7DIOGxx4VWXoCEeYYarFYeERTpWIC1V3y-BPZgKE'; //749180
//const interactionsLoader = new FromFileInteractionsLoader(path.join(__dirname, 'data', 'interactions.json'));
@@ -60,19 +60,19 @@ async function main() {
});*/
const smartweave = SmartWeaveWebFactory.memCached(arweave);
const contract = smartweave.contract(contractTxId).setEvaluationOptions({
updateCacheForEachInteraction: false
const contract = smartweaveR.contract(contractTxId).setEvaluationOptions({
updateCacheForEachInteraction: true
});
const result = await contract.readState();
const result2 = await readContract(arweave, "t9T7DIOGxx4VWXoCEeYYarFYeERTpWIC1V3y-BPZgKE")
//const result2 = await readContract(arweave, "t9T7DIOGxx4VWXoCEeYYarFYeERTpWIC1V3y-BPZgKE")
//fs.writeFileSync(path.join(__dirname, 'data', 'validity.json'), JSON.stringify(validity));
//fs.writeFileSync(path.join(__dirname, 'data', 'validity_old.json'), JSON.stringify(result.validity));
fs.writeFileSync(path.join(__dirname, 'data', 'state_new.json'), stringify(result.state).trim());
fs.writeFileSync(path.join(__dirname, 'data', 'state_old.json'), stringify(result2).trim());
//fs.writeFileSync(path.join(__dirname, 'data', 'state_old.json'), stringify(result2).trim());
//fs.writeFileSync(path.join(__dirname, 'data', 'state_arweave.json'), JSON.stringify(result.state));
// console.log('second read');

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long