From a5ba8d4352f647ad384981264cb6e0553481f23b Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Mon, 2 Oct 2023 13:30:04 -0500 Subject: [PATCH] Evaluate append vs copy. Apply results --- beacon-chain/state/state-native/BUILD.bazel | 2 + .../state/state-native/setters_attestation.go | 2 +- .../state-native/setters_attestation_test.go | 20 +++--- .../state/state-native/setters_eth1.go | 2 +- .../state/state-native/setters_eth1_test.go | 36 +++++----- .../state/state-native/setters_misc.go | 4 +- .../state/state-native/setters_misc_test.go | 66 +++++++++---------- .../state-native/setters_participation.go | 8 +-- .../setters_participation_test.go | 27 ++++++++ .../state/state-native/setters_validator.go | 4 +- .../state-native/setters_validator_test.go | 45 +++++++++++++ 11 files changed, 146 insertions(+), 70 deletions(-) create mode 100644 beacon-chain/state/state-native/setters_participation_test.go create mode 100644 beacon-chain/state/state-native/setters_validator_test.go diff --git a/beacon-chain/state/state-native/BUILD.bazel b/beacon-chain/state/state-native/BUILD.bazel index 57d31ae07f..6949ffb4a2 100644 --- a/beacon-chain/state/state-native/BUILD.bazel +++ b/beacon-chain/state/state-native/BUILD.bazel @@ -88,6 +88,8 @@ go_test( "setters_attestation_test.go", "setters_eth1_test.go", "setters_misc_test.go", + "setters_participation_test.go", + "setters_validator_test.go", "setters_withdrawal_test.go", "state_fuzz_test.go", "state_test.go", diff --git a/beacon-chain/state/state-native/setters_attestation.go b/beacon-chain/state/state-native/setters_attestation.go index 1a070623ed..d6595b28ac 100644 --- a/beacon-chain/state/state-native/setters_attestation.go +++ b/beacon-chain/state/state-native/setters_attestation.go @@ -91,7 +91,7 @@ func (b *BeaconState) AppendPreviousEpochAttestations(val *ethpb.PendingAttestat if b.sharedFieldReferences[types.PreviousEpochAttestations].Refs() > 1 { atts = make([]*ethpb.PendingAttestation, 0, len(b.previousEpochAttestations)+1) - atts = append(atts, b.previousEpochAttestations...) + copy(atts, b.previousEpochAttestations) b.sharedFieldReferences[types.PreviousEpochAttestations].MinusRef() b.sharedFieldReferences[types.PreviousEpochAttestations] = stateutil.NewRef(1) } diff --git a/beacon-chain/state/state-native/setters_attestation_test.go b/beacon-chain/state/state-native/setters_attestation_test.go index 7302b21b53..19576dab20 100644 --- a/beacon-chain/state/state-native/setters_attestation_test.go +++ b/beacon-chain/state/state-native/setters_attestation_test.go @@ -81,18 +81,20 @@ func BenchmarkAppendPreviousEpochAttestations(b *testing.B) { max := uint64(params.BeaconConfig().PreviousEpochAttestationsLength()) if max < 2 { - b.Fatalf("previous epoch attestations length is less than 2: %d", max) + b.Fatalf("previous epoch attestations length is less than 2: %d", max) } - for i := uint64(0); i < max-2; i++ { - err := st.AppendPreviousEpochAttestations(ðpb.PendingAttestation{Data: ðpb.AttestationData{Slot: primitives.Slot(i)}}) - require.NoError(b, err) - } + for i := uint64(0); i < max-2; i++ { + err := st.AppendPreviousEpochAttestations(ðpb.PendingAttestation{Data: ðpb.AttestationData{Slot: primitives.Slot(i)}}) + require.NoError(b, err) + } - ref := st.Copy() + b.ResetTimer() + + ref := st.Copy() for i := 0; i < b.N; i++ { - err := ref.AppendPreviousEpochAttestations(ðpb.PendingAttestation{Data: ðpb.AttestationData{Slot: primitives.Slot(i)}}) - require.NoError(b, err) - ref = st.Copy() + err := ref.AppendPreviousEpochAttestations(ðpb.PendingAttestation{Data: ðpb.AttestationData{Slot: primitives.Slot(i)}}) + require.NoError(b, err) + ref = st.Copy() } } diff --git a/beacon-chain/state/state-native/setters_eth1.go b/beacon-chain/state/state-native/setters_eth1.go index 6822900e2e..0313d6d06e 100644 --- a/beacon-chain/state/state-native/setters_eth1.go +++ b/beacon-chain/state/state-native/setters_eth1.go @@ -51,7 +51,7 @@ func (b *BeaconState) AppendEth1DataVotes(val *ethpb.Eth1Data) error { if b.sharedFieldReferences[types.Eth1DataVotes].Refs() > 1 { // Copy elements in underlying array by reference. votes = make([]*ethpb.Eth1Data, 0, len(b.eth1DataVotes)+1) - votes = append(votes, b.eth1DataVotes...) + copy(votes, b.eth1DataVotes) b.sharedFieldReferences[types.Eth1DataVotes].MinusRef() b.sharedFieldReferences[types.Eth1DataVotes] = stateutil.NewRef(1) } diff --git a/beacon-chain/state/state-native/setters_eth1_test.go b/beacon-chain/state/state-native/setters_eth1_test.go index a69c0bf192..90a4e197c4 100644 --- a/beacon-chain/state/state-native/setters_eth1_test.go +++ b/beacon-chain/state/state-native/setters_eth1_test.go @@ -14,26 +14,26 @@ func BenchmarkAppendEth1DataVotes(b *testing.B) { st, err := state_native.InitializeFromProtoPhase0(ðpb.BeaconState{}) require.NoError(b, err) - max := params.BeaconConfig().Eth1DataVotesLength() + max := params.BeaconConfig().Eth1DataVotesLength() - if max < 2 { - b.Fatalf("Eth1DataVotesLength is less than 2") - } + if max < 2 { + b.Fatalf("Eth1DataVotesLength is less than 2") + } - for i := uint64(0); i < max-2; i++ { - err := st.AppendEth1DataVotes(ðpb.Eth1Data{ - DepositCount: i, - DepositRoot: make([]byte, 64), - BlockHash: make([]byte, 64), - }) - require.NoError(b, err) - } + for i := uint64(0); i < max-2; i++ { + err := st.AppendEth1DataVotes(ðpb.Eth1Data{ + DepositCount: i, + DepositRoot: make([]byte, 64), + BlockHash: make([]byte, 64), + }) + require.NoError(b, err) + } - ref := st.Copy() + ref := st.Copy() - for i := 0; i < b.N; i++ { - err := ref.AppendEth1DataVotes(ð.Eth1Data{DepositCount: uint64(i)}) - require.NoError(b, err) - ref = st.Copy() - } + for i := 0; i < b.N; i++ { + err := ref.AppendEth1DataVotes(ð.Eth1Data{DepositCount: uint64(i)}) + require.NoError(b, err) + ref = st.Copy() + } } diff --git a/beacon-chain/state/state-native/setters_misc.go b/beacon-chain/state/state-native/setters_misc.go index d94f94f9b7..a316f2bcbe 100644 --- a/beacon-chain/state/state-native/setters_misc.go +++ b/beacon-chain/state/state-native/setters_misc.go @@ -119,7 +119,7 @@ func (b *BeaconState) AppendHistoricalRoots(root [32]byte) error { roots := b.historicalRoots if b.sharedFieldReferences[types.HistoricalRoots].Refs() > 1 { roots = make([][32]byte, 0, len(b.historicalRoots)+1) - roots = append(roots, b.historicalRoots...) + copy(roots, b.historicalRoots) b.sharedFieldReferences[types.HistoricalRoots].MinusRef() b.sharedFieldReferences[types.HistoricalRoots] = stateutil.NewRef(1) } @@ -142,7 +142,7 @@ func (b *BeaconState) AppendHistoricalSummaries(summary *ethpb.HistoricalSummary summaries := b.historicalSummaries if b.sharedFieldReferences[types.HistoricalSummaries].Refs() > 1 { summaries = make([]*ethpb.HistoricalSummary, 0, len(b.historicalSummaries)+1) - summaries = append(summaries, b.historicalSummaries...) + copy(summaries, b.historicalSummaries) b.sharedFieldReferences[types.HistoricalSummaries].MinusRef() b.sharedFieldReferences[types.HistoricalSummaries] = stateutil.NewRef(1) } diff --git a/beacon-chain/state/state-native/setters_misc_test.go b/beacon-chain/state/state-native/setters_misc_test.go index f3790ee2fa..1b4e863a61 100644 --- a/beacon-chain/state/state-native/setters_misc_test.go +++ b/beacon-chain/state/state-native/setters_misc_test.go @@ -14,49 +14,49 @@ func BenchmarkAppendHistoricalRoots(b *testing.B) { st, err := state_native.InitializeFromProtoPhase0(ðpb.BeaconState{}) require.NoError(b, err) - max := params.BeaconConfig().HistoricalRootsLimit - if max < 2 { - b.Fatalf("HistoricalRootsLimit is less than 2: %d", max) - } + max := params.BeaconConfig().HistoricalRootsLimit + if max < 2 { + b.Fatalf("HistoricalRootsLimit is less than 2: %d", max) + } - root := bytesutil.ToBytes32([]byte{0, 1, 2, 3, 4, 5}) - for i := uint64(0); i < max-2; i++{ - err := st.AppendHistoricalRoots(root) - require.NoError(b, err) - } - - ref := st.Copy() + root := bytesutil.ToBytes32([]byte{0, 1, 2, 3, 4, 5}) + for i := uint64(0); i < max-2; i++ { + err := st.AppendHistoricalRoots(root) + require.NoError(b, err) + } - b.ResetTimer() + ref := st.Copy() - for i := 0; i < b.N; i++ { - err := ref.AppendHistoricalRoots(root) - require.NoError(b, err) - ref = st.Copy() - } + b.ResetTimer() + + for i := 0; i < b.N; i++ { + err := ref.AppendHistoricalRoots(root) + require.NoError(b, err) + ref = st.Copy() + } } func BenchmarkAppendHistoricalSummaries(b *testing.B) { st, err := state_native.InitializeFromProtoCapella(ðpb.BeaconStateCapella{}) require.NoError(b, err) - max := params.BeaconConfig().HistoricalRootsLimit - if max < 2 { - b.Fatalf("HistoricalRootsLimit is less than 2: %d", max) - } + max := params.BeaconConfig().HistoricalRootsLimit + if max < 2 { + b.Fatalf("HistoricalRootsLimit is less than 2: %d", max) + } - for i := uint64(0); i < max-2; i++{ - err := st.AppendHistoricalSummaries(ðpb.HistoricalSummary{}) - require.NoError(b, err) - } - - ref := st.Copy() + for i := uint64(0); i < max-2; i++ { + err := st.AppendHistoricalSummaries(ðpb.HistoricalSummary{}) + require.NoError(b, err) + } - b.ResetTimer() + ref := st.Copy() - for i := 0; i < b.N; i++ { - err := ref.AppendHistoricalSummaries(ðpb.HistoricalSummary{}) - require.NoError(b, err) - ref = st.Copy() - } + b.ResetTimer() + + for i := 0; i < b.N; i++ { + err := ref.AppendHistoricalSummaries(ðpb.HistoricalSummary{}) + require.NoError(b, err) + ref = st.Copy() + } } diff --git a/beacon-chain/state/state-native/setters_participation.go b/beacon-chain/state/state-native/setters_participation.go index 796ae1ce64..5da8582348 100644 --- a/beacon-chain/state/state-native/setters_participation.go +++ b/beacon-chain/state/state-native/setters_participation.go @@ -58,7 +58,7 @@ func (b *BeaconState) AppendCurrentParticipationBits(val byte) error { if b.sharedFieldReferences[types.CurrentEpochParticipationBits].Refs() > 1 { // Copy elements in underlying array by reference. participation = make([]byte, 0, len(b.currentEpochParticipation)+1) - participation = append(participation, b.currentEpochParticipation...) + copy(participation, b.currentEpochParticipation) b.sharedFieldReferences[types.CurrentEpochParticipationBits].MinusRef() b.sharedFieldReferences[types.CurrentEpochParticipationBits] = stateutil.NewRef(1) } @@ -82,7 +82,7 @@ func (b *BeaconState) AppendPreviousParticipationBits(val byte) error { bits := b.previousEpochParticipation if b.sharedFieldReferences[types.PreviousEpochParticipationBits].Refs() > 1 { bits = make([]byte, 0, len(b.previousEpochParticipation)+1) - bits = append(bits, b.previousEpochParticipation...) + copy(bits, b.previousEpochParticipation) b.sharedFieldReferences[types.PreviousEpochParticipationBits].MinusRef() b.sharedFieldReferences[types.PreviousEpochParticipationBits] = stateutil.NewRef(1) } @@ -108,7 +108,7 @@ func (b *BeaconState) ModifyPreviousParticipationBits(mutator func(val []byte) ( if b.sharedFieldReferences[types.PreviousEpochParticipationBits].Refs() > 1 { // Copy elements in underlying array by reference. participation = make([]byte, 0, len(b.previousEpochParticipation)+1) - participation = append(participation, b.previousEpochParticipation...) + copy(participation, b.previousEpochParticipation) b.sharedFieldReferences[types.PreviousEpochParticipationBits].MinusRef() b.sharedFieldReferences[types.PreviousEpochParticipationBits] = stateutil.NewRef(1) } @@ -143,7 +143,7 @@ func (b *BeaconState) ModifyCurrentParticipationBits(mutator func(val []byte) ([ if b.sharedFieldReferences[types.CurrentEpochParticipationBits].Refs() > 1 { // Copy elements in underlying array by reference. participation = make([]byte, 0, len(b.currentEpochParticipation)+1) - participation = append(participation, b.currentEpochParticipation...) + copy(participation, b.currentEpochParticipation) b.sharedFieldReferences[types.CurrentEpochParticipationBits].MinusRef() b.sharedFieldReferences[types.CurrentEpochParticipationBits] = stateutil.NewRef(1) } diff --git a/beacon-chain/state/state-native/setters_participation_test.go b/beacon-chain/state/state-native/setters_participation_test.go new file mode 100644 index 0000000000..feb1bf9510 --- /dev/null +++ b/beacon-chain/state/state-native/setters_participation_test.go @@ -0,0 +1,27 @@ +package state_native_test + +import ( + "testing" + + state_native "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native" + ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/v4/testing/require" +) + +func BenchmarkParticipationBits(b *testing.B) { + st, err := state_native.InitializeFromProtoCapella(ðpb.BeaconStateCapella{}) + require.NoError(b, err) + + max := uint64(16777216) + for i := uint64(0); i < max-2; i++ { + require.NoError(b, st.AppendCurrentParticipationBits(byte(1))) + } + + ref := st.Copy() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + require.NoError(b, ref.AppendCurrentParticipationBits(byte(2))) + ref = st.Copy() + } +} diff --git a/beacon-chain/state/state-native/setters_validator.go b/beacon-chain/state/state-native/setters_validator.go index abeb64dec0..5def007aa7 100644 --- a/beacon-chain/state/state-native/setters_validator.go +++ b/beacon-chain/state/state-native/setters_validator.go @@ -191,7 +191,7 @@ func (b *BeaconState) AppendBalance(bal uint64) error { bals := b.balances if b.sharedFieldReferences[types.Balances].Refs() > 1 { bals = make([]uint64, 0, len(b.balances)+1) - bals = append(bals, b.balances...) + copy(bals, b.balances) b.sharedFieldReferences[types.Balances].MinusRef() b.sharedFieldReferences[types.Balances] = stateutil.NewRef(1) } @@ -215,7 +215,7 @@ func (b *BeaconState) AppendInactivityScore(s uint64) error { scores := b.inactivityScores if b.sharedFieldReferences[types.InactivityScores].Refs() > 1 { scores = make([]uint64, 0, len(b.inactivityScores)+1) - scores = append(scores, b.inactivityScores...) + copy(scores, b.inactivityScores) b.sharedFieldReferences[types.InactivityScores].MinusRef() b.sharedFieldReferences[types.InactivityScores] = stateutil.NewRef(1) } diff --git a/beacon-chain/state/state-native/setters_validator_test.go b/beacon-chain/state/state-native/setters_validator_test.go new file mode 100644 index 0000000000..2de5e49b27 --- /dev/null +++ b/beacon-chain/state/state-native/setters_validator_test.go @@ -0,0 +1,45 @@ +package state_native_test + +import ( + "testing" + + state_native "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native" + ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/v4/testing/require" +) + +func BenchmarkAppendBalance(b *testing.B) { + st, err := state_native.InitializeFromProtoPhase0(ðpb.BeaconState{}) + require.NoError(b, err) + + max := uint64(16777216) + for i := uint64(0); i < max-2; i++ { + require.NoError(b, st.AppendBalance(i)) + } + + ref := st.Copy() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + require.NoError(b, ref.AppendBalance(uint64(i))) + ref = st.Copy() + } +} + +func BenchmarkAppendInactivityScore(b *testing.B) { + st, err := state_native.InitializeFromProtoCapella(ðpb.BeaconStateCapella{}) + require.NoError(b, err) + + max := uint64(16777216) + for i := uint64(0); i < max-2; i++ { + require.NoError(b, st.AppendInactivityScore(i)) + } + + ref := st.Copy() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + require.NoError(b, ref.AppendInactivityScore(uint64(i))) + ref = st.Copy() + } +}