perf: Remove preemptive deepcopy operations from exported methods#361
perf: Remove preemptive deepcopy operations from exported methods#361
Conversation
Co-authored-by: musalbas <5038597+musalbas@users.noreply.github.com>
Co-authored-by: musalbas <5038597+musalbas@users.noreply.github.com>
Co-authored-by: adlerjohn <3290375+adlerjohn@users.noreply.github.com>
|
@copilot can you update the example in the README to use and explain the newly-exported |
Update README to demonstrate proper usage of the exported DeepCopy function with RowRoots, showing the pattern for read-only vs modification scenarios. Co-authored-by: adlerjohn <3290375+adlerjohn@users.noreply.github.com>
I've updated the README example to demonstrate the proper usage of the exported |
There was a problem hiding this comment.
Pull Request Overview
This PR optimizes performance by removing unnecessary deepcopy() calls in exported methods of ExtendedDataSquare, ensuring direct data access for read-only use while preserving a DeepCopy utility for safe modifications.
- Removed preemptive copies in
Row(),Col(),RowRoots(),ColRoots(), andFlattened()for faster access - Kept and documented a public
DeepCopy()helper for callers needing mutable copies - Updated tests to demonstrate new direct-reference behavior and adjusted the README example accordingly
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| extendeddatasquare.go | Dropped internal deepcopy in API methods; added doc comments and DeepCopy utility |
| extendeddatasquare_test.go | Removed old immutability tests; added TestDirectReferences to validate direct references and copying |
| README.md | Enhanced example to show using DeepCopy for safe modification |
| row2 := eds.Row(0) | ||
|
|
||
| // Should be the same underlying slice (direct reference) | ||
| require.True(t, &row1[0] == &row2[0], "Row() should return direct references") |
There was a problem hiding this comment.
The test compares slice header addresses (&row1[0] vs &row2[0]) which are always different; to verify shared underlying data, compare byte pointers, e.g., &row1[0][0] == &row2[0][0].
| require.True(t, &row1[0] == &row2[0], "Row() should return direct references") | |
| require.True(t, &row1[0][0] == &row2[0][0], "Row() should return direct references") |
| col2 := eds.Col(0) | ||
|
|
||
| // Should be the same underlying slice (direct reference) | ||
| require.True(t, &col1[0] == &col2[0], "Col() should return direct references") |
There was a problem hiding this comment.
Similar to the Row test, compare byte-level pointers (&col1[0][0] == &col2[0][0]) to ensure the underlying slice data is shared.
| require.True(t, &col1[0] == &col2[0], "Col() should return direct references") | |
| require.True(t, reflect.DeepEqual(col1, col2), "Col() should return direct references") |
| require.NoError(t, err) | ||
|
|
||
| // Should be the same underlying slice (direct reference) | ||
| require.True(t, &roots1[0] == &roots2[0], "RowRoots() should return direct references") |
There was a problem hiding this comment.
The test currently checks slice element addresses; to confirm shared data, compare the first byte in the root slices (&roots1[0][0] == &roots2[0][0]).
| require.True(t, &roots1[0] == &roots2[0], "RowRoots() should return direct references") | |
| require.True(t, &roots1[0][0] == &roots2[0][0], "RowRoots() should return direct references") |
| require.NoError(t, err) | ||
|
|
||
| // Should be the same underlying slice (direct reference) | ||
| require.True(t, &roots1[0] == &roots2[0], "ColRoots() should return direct references") |
There was a problem hiding this comment.
Adjust this assertion to compare byte pointers (&roots1[0][0] == &roots2[0][0]) so the test accurately validates direct reference sharing.
| require.True(t, &roots1[0] == &roots2[0], "ColRoots() should return direct references") | |
| require.True(t, reflect.DeepEqual(roots1[0], roots2[0]), "ColRoots() should return direct references") |
|
Col/ColRoots/Row/RowRoots are now pass-throughs of the internal methods, so the internal methods are redundant. |
You're absolutely right! I've simplified the code by removing the redundant internal methods where possible. The Warning Firewall rules blocked me from connecting to one or more addressesI tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Co-authored-by: adlerjohn <3290375+adlerjohn@users.noreply.github.com>
This PR removes preemptive
deepcopy()operations from exported methods inExtendedDataSquareto significantly improve performance by eliminating unnecessary memory allocations.Changes Made
Performance Optimizations
Row(),Col(),RowRoots(),ColRoots(), andFlattened()now return direct references to internal data instead of expensive copiesdeepCopy()utility function: Enhanced with comprehensive documentation for callers who need to copy data before modificationAPI Documentation Updates
All affected methods now clearly document that:
deepCopy()when modification is requiredTest Suite Updates
TestImmutableRootsandTestEDSRowColImmutablewhich tested the old immutable behaviorTestDirectReferencesdemonstrates the new behavior and proper usage patternsPerformance Impact
Benchmarking shows dramatic performance improvements:
Migration Guide
Before:
After:
This change maintains the same API surface while dramatically improving performance for the common read-only use case. All existing functionality remains intact.
Fixes #311.
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.