diff --git a/src/init.cpp b/src/init.cpp index 656bda64..9735c278 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -481,6 +481,7 @@ bool AppInit2() // ********************************************************* Step 3: parameter-to-internal-flags fDebug = GetBoolArg("-debug"); + fBenchmark = GetBoolArg("-benchmark"); // -debug implies fDebug* if (fDebug) diff --git a/src/main.cpp b/src/main.cpp index 693cb28d..61bd6b7b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -42,6 +42,7 @@ set setBlockIndexValid; // may contain int64 nTimeBestReceived = 0; bool fImporting = false; bool fReindex = false; +bool fBenchmark = false; unsigned int nCoinCacheSize = 5000; CMedianFilter cPeerBlockCounts(5, 0); // Amount of blocks that other nodes claim to have @@ -1593,12 +1594,16 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJust CBlockUndo blockundo; + int64 nStart = GetTimeMicros(); int64 nFees = 0; + int nInputs = 0; unsigned int nSigOps = 0; for (unsigned int i=0; i MAX_BLOCK_SIGOPS) return DoS(100, error("ConnectBlock() : too many sigops")); @@ -1629,7 +1634,11 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJust return error("ConnectBlock() : UpdateInputs failed"); if (!tx.IsCoinBase()) blockundo.vtxundo.push_back(txundo); + } + int64 nTime = GetTimeMicros() - nStart; + if (fBenchmark) + printf("- Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin)\n", (unsigned)vtx.size(), 0.001 * nTime, 0.001 * nTime / vtx.size(), nInputs <= 1 ? 0 : 0.001 * nTime / (nInputs-1)); if (vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees)) return error("ConnectBlock() : coinbase pays too much (actual=%"PRI64d" vs limit=%"PRI64d")", vtx[0].GetValueOut(), GetBlockValue(pindex->nHeight, nFees)); @@ -1727,8 +1736,11 @@ bool SetBestChain(CBlockIndex* pindexNew) CBlock block; if (!block.ReadFromDisk(pindex)) return error("SetBestBlock() : ReadFromDisk for disconnect failed"); + int64 nStart = GetTimeMicros(); if (!block.DisconnectBlock(pindex, view)) return error("SetBestBlock() : DisconnectBlock %s failed", BlockHashStr(pindex->GetBlockHash()).c_str()); + if (fBenchmark) + printf("- Disconnect: %.2fms\n", (GetTimeMicros() - nStart) * 0.001); // Queue memory transactions to resurrect. // We only do this for blocks after the last checkpoint (reorganisation before that @@ -1744,11 +1756,14 @@ bool SetBestChain(CBlockIndex* pindexNew) CBlock block; if (!block.ReadFromDisk(pindex)) return error("SetBestBlock() : ReadFromDisk for connect failed"); + int64 nStart = GetTimeMicros(); if (!block.ConnectBlock(pindex, view)) { InvalidChainFound(pindexNew); InvalidBlockFound(pindex); return error("SetBestBlock() : ConnectBlock %s failed", BlockHashStr(pindex->GetBlockHash()).c_str()); } + if (fBenchmark) + printf("- Connect: %.2fms\n", (GetTimeMicros() - nStart) * 0.001); // Queue memory transactions to delete BOOST_FOREACH(const CTransaction& tx, block.vtx) @@ -1756,8 +1771,13 @@ bool SetBestChain(CBlockIndex* pindexNew) } // Flush changes to global coin state + int64 nStart = GetTimeMicros(); + int nModified = view.GetCacheSize(); if (!view.Flush()) return error("SetBestBlock() : unable to modify coin state"); + int64 nTime = GetTimeMicros() - nStart; + if (fBenchmark) + printf("- Flush %i transactions: %.2fms (%.4fms/tx)\n", nModified, 0.001 * nTime, 0.001 * nTime / nModified); // Make sure it's successfully written to disk before changing memory structure bool fIsInitialDownload = IsInitialBlockDownload(); diff --git a/src/main.h b/src/main.h index fbd68127..fdaec346 100644 --- a/src/main.h +++ b/src/main.h @@ -89,6 +89,7 @@ extern std::set setpwalletRegistered; extern unsigned char pchMessageStart[4]; extern bool fImporting; extern bool fReindex; +extern bool fBenchmark; extern unsigned int nCoinCacheSize; // Settings diff --git a/src/util.h b/src/util.h index d8203b58..ab921e6f 100644 --- a/src/util.h +++ b/src/util.h @@ -330,6 +330,12 @@ inline int64 GetTimeMillis() boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds(); } +inline int64 GetTimeMicros() +{ + return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) - + boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds(); +} + inline std::string DateTimeStrFormat(const char* pszFormat, int64 nTime) { time_t n = nTime;