以太坊Trie的写入读取测试

环境

Windows 11,AMD R7 8核 16 线程处理器,16GB内存。

测试内容

随机写入1000w条账户数据。然后从写入的1000w条数据随机读取1000,10000,100000,1000000条数据。

测试结果

写入结果

随机写入1000w条数据,总花费时间350s左右,所以写入的TPS大概为 10000000 / 350 == 28571TPS

这是随机写入各个阶段分别花费的时间

在内存中构建整颗trie内容:TryUpdate spend time 24.3511507s
对构建的trie进行哈希计算:Hash spend time 29.2529906s
将内存中的trie提交到trie对应的内存数据库中:Commit spend time 93.6990205s
将内存数据库中的数据提交到leveldb:Commit to leveldb spend time 201.5279795s

读取结果

这是随机读取1000,10000,100000,1000000条数据所花费的时间

读取 1000 条,花费时间 1.19s,此时 840TPS
读取 10000 条,花费时间 8.26s,此时 1210TPS
读取 100000 条,花费时间 54.34s,此时 1840TPS
读取 1000000 条,花费时间 330s,此时 3030TPS

从上面可以看出,当一次性读取的数据越多的时候,TPS越高,因为读出来的中间节点已经在内存中缓存起来了的缘故。当从leveldb中加载到内存中再次读取的时候,读取的时间几乎可以忽略不记。比如读取10w条完毕之后,再把这10w条读一次加起来的时间跟第一次读取10w条的数据一摸一样。所以假设真实情景读取时按照从缓存读取一半从leveldb读取一半来计算,理论TPS大概是2000左右。

其他

1000w条写完之后大概占用内存为1.7GB左右。写入的数据一个账户的 key 为32字节,账户的数据大概为 100 字节。一共需要1.32GB,与1.7GB大概相差380MB左右。

测试代码

写入测试:

func IntToByte(num int) []byte {
    data := int64(num)
    var buffer bytes.Buffer
    binary.Write(&buffer, binary.BigEndian, data)
    return buffer.Bytes()
}

// 10000000 count account
// TryUpdate spend time 24.3511507s
// Hash spend time 29.2529906s
// Commit spend time 93.6990205s
// Commit to leveldb spend time 201.5279795s
// root 0x624b8710c478c9dd60d627b308a30d3c6e59f7199b2586a8e31af8bbab254efd
// 10000000 / 360 == 27777
func TestTpsWrite(t *testing.T) {
    usr, _ := user.Current()
    dir := filepath.Join(usr.HomeDir, "trie-tps")
    dbPath := path.Join(dir, "trie")
    diskdb, _ := leveldb.New(dbPath, 256, 0, "", false)
    trie, _ := New(emptyRoot, NewDatabase(diskdb))

    count := 10000000
    addresses := make([][32]byte, count)
    for i := 0; i < len(addresses); i++ {
        data := IntToByte(i)
        copy(addresses[i][:], crypto.Keccak256(data))
    }

    random := rand.New(rand.NewSource(0))
    accounts := make([][]byte, len(addresses))
    for i := 0; i < len(accounts); i++ {
        var (
            nonce = uint64(random.Int63())
            root  = emptyRoot
            code  = emptyState
        )
        numBytes := random.Uint32() % 33 // [0, 32] bytes
        balanceBytes := make([]byte, numBytes)
        random.Read(balanceBytes)
        balance := new(big.Int).SetBytes(balanceBytes)
        data, _ := rlp.EncodeToBytes(&account{nonce, balance, root, code[:]})
        accounts[i] = data
    }

    t.Logf("%d count account", count)

    var start time.Time
    var cost time.Duration

    start = time.Now()
    for i := 0; i < count; i++ {
        trie.TryUpdate(addresses[i][:], accounts[i])
    }
    cost = time.Since(start)
    t.Logf("TryUpdate spend time %s", cost)

    start = time.Now()
    trie.Hash()
    cost = time.Since(start)
    t.Logf("Hash spend time %s", cost)

    start = time.Now()
    root, _, _ := trie.Commit(nil)
    cost = time.Since(start)
    t.Logf("Commit spend time %s", cost)

    start = time.Now()
    trie.db.Commit(root, false, nil)
    cost = time.Since(start)
    t.Logf("Commit to leveldb spend time %s", cost)
    t.Logf("root %s", root.String())

    trie.db.diskdb.(*leveldb.Database).Close()
}

读取测试(需要更改count测试读取结果):

// 1000 1.19s 840TPS
// 10000 8.26s 1210TPS
// 100000 54.34s 1840TPS
// 1000000 330s 3030TPS
func TestTpsRead(t *testing.T) {
    usr, _ := user.Current()
    dir := filepath.Join(usr.HomeDir, "trie-tps")
    dbPath := path.Join(dir, "trie")
    diskdb, _ := leveldb.New(dbPath, 256, 0, "", false)
    trie, _ := New(common.HexToHash("0x624b8710c478c9dd60d627b308a30d3c6e59f7199b2586a8e31af8bbab254efd"), NewDatabase(diskdb))

    count := 100000
    addresses := make([][32]byte, count)
    for i := 0; i < len(addresses); i++ {
        data := IntToByte(i)
        copy(addresses[i][:], crypto.Keccak256(data))
    }

    t.Logf("%d count account", count)

    var start time.Time
    var cost time.Duration

    start = time.Now()
    for i := 0; i < count; i++ {
        trie.TryGet(addresses[i][:])
    }

    cost = time.Since(start)
    t.Logf("TryGet spend time %s", cost)
    trie.db.diskdb.(*leveldb.Database).Close()
}
暂无评论

发送评论 编辑评论


				
上一篇
下一篇