Version 2.0.0
Breaking
- Now targets .NET 8.0 and .NET 9.0
PhpTokenizer
class is now internal.- Removed support for
net6.0
andnet7.0
. - The default implicit type for numeric values is now
int
instead oflong
1.x:PhpSerialization.Deserialize("i:42;") == 42L
2.x:PhpSerialization.Deserialize("i:42;") == 42
- Changed the signature of
[PhpPropery(long)]
to[PhpPropery(int)]
to align with the above change.
Features
- Added
PhpSerialization.DeserializeUtf8(ReadOnlySpan<byte>)
overloads for cases in which consumers directly work with
UTF8 inputs and can skip the re-encoding. - Added
PhpSerializationFilter
attribute base class, allowing customization of class and struct member serialization.
See thePhpSerializationFilterTest
for an example. See also Issue #33.
Regular changes
- Integers and doubles without a value now give a better error message (
i:;
andd:;
).
Performance
- Reduced time to decode / re-encode the input string.
- Reduced memory allocations both in the input re-encoding and the deserialization.
- Delay the materialization of strings when deserializing. This can avoid string allocations entirely for integers,
doubles and booleans. - Improved performance for implicit deserialization of integers as well as minor improvements for implicit
deserialization of arrays. - Improved serialization performance for strings, integers,
IList<T>
,ExpandoObject
, Dictionaries andPhpDynamicObject
Internal
Split the deserialization into 3 phases:
- Validation of the input and counting of the data tokens.
- Parsing of the input into tokens
- Deserializations of the tokens into the target C# objects/structs.
In version 1.4 and prior, this was a 2 step process. This is slightly slower on some inputs, but overall a little
neater because we're cleanly separating the tasks.
Some benchmark results:
Version | Input | Mean | Allocated |
---|---|---|---|
1.4.0 | a:0:{} | 61.78 ns | 248 B |
2.0.0 | a:0:{} | 29.81 ns | 80 B |
1.4.0 | a:3:{i:0;s:5:"Hello";i:1;s:5:"World";i:2;s:6:"FooBar";} | 243.96 ns | 816 B |
2.0.0 | a:3:{i:0;s:5:"Hello";i:1;s:5:"World";i:2;s:6:"FooBar";} | 149.83 ns | 352 B |
1.4.0 | b:1; | 50.49 ns | 208 B |
2.0.0 | b:1; | 21.65 ns | 72 B |
1.4.0 | i:2147483647; | 79.66 ns | 296 B |
2.0.0 | i:2147483647; | 32.13 ns | 72 B |
1.4.0 | N; | 45.53 ns | 184 B |
2.0.0 | N; | 20.57 ns | 48 B |
1.4.0 | O:8:"stdClass":0:{} | 97.71 ns | 400 B |
2.0.0 | O:8:"stdClass":0:{} | 56.86 ns | 176 B |
1.4.0 | O:8:"stdClass":2:{s:4:"John";d:3.14;s:4:"Jane";d:2.718;} | 307.86 ns | 992 B |
2.0.0 | O:8:"stdClass":2:{s:4:"John";d:3.14;s:4:"Jane";d:2.718;} | 206.99 ns | 504 B |
1.4.0 | s:12:"Hello World!"; | 72.20 ns | 296 B |
2.0.0 | s:12:"Hello World!"; | 36.02 ns | 96 B |