Optimize GC for PropSrc.

This commit is contained in:
2022-12-25 22:20:46 +08:00
parent e589e37640
commit 44180c7e0f
3 changed files with 49 additions and 38 deletions

View File

@@ -244,17 +244,17 @@ namespace Cryville.Crtr {
_buf = null; _buf = null;
} }
} }
protected override unsafe void InternalGet(out int type, out byte[] value) { protected override unsafe int InternalGet() {
var src = _cb(); var src = _cb();
int strlen = src.Length; int strlen = src.Length;
type = PdtInternalType.String; buf = _pool.Rent(sizeof(int) + strlen * sizeof(char));
value = _pool.Rent(sizeof(int) + strlen * sizeof(char)); fixed (byte* _ptr = buf) {
fixed (byte* _ptr = value) {
char* ptr = (char*)(_ptr + sizeof(int)); char* ptr = (char*)(_ptr + sizeof(int));
*(int*)_ptr = strlen; *(int*)_ptr = strlen;
int i = 0; int i = 0;
foreach (var c in src) ptr[i++] = c; foreach (var c in src) ptr[i++] = c;
} }
return PdtInternalType.String;
} }
} }
#endregion #endregion

View File

@@ -928,25 +928,25 @@ namespace Cryville.Crtr {
public class VectorSrc : PropSrc { public class VectorSrc : PropSrc {
readonly Func<Vector> _cb; readonly Func<Vector> _cb;
public VectorSrc(Func<Vector> cb) { _cb = cb; } public VectorSrc(Func<Vector> cb) { _cb = cb; }
protected override unsafe void InternalGet(out int type, out byte[] value) { protected override unsafe int InternalGet() {
var arr = _cb().ToArray(); var arr = _cb().ToArray();
if (arr.Length == 1) { if (arr.Length == 1) {
type = PdtInternalType.Number; buf = new byte[sizeof(float)];
value = new byte[sizeof(float)]; fixed (byte* ptr = buf) {
fixed (byte* ptr = value) {
*(float*)ptr = arr[0]; *(float*)ptr = arr[0];
} }
return PdtInternalType.Number;
} }
else { else {
type = PdtInternalType.Vector; buf = new byte[sizeof(float) * arr.Length + sizeof(int)];
value = new byte[sizeof(float) * arr.Length + sizeof(int)]; fixed (byte* rptr = buf) {
fixed (byte* rptr = value) {
var ptr = (float*)rptr; var ptr = (float*)rptr;
for (int i = 0; i < arr.Length; i++, ptr++) { for (int i = 0; i < arr.Length; i++, ptr++) {
*ptr = arr[i]; *ptr = arr[i];
} }
*(int*)ptr = PdtInternalType.Number; *(int*)ptr = PdtInternalType.Number;
} }
return PdtInternalType.Vector;
} }
} }
} }

View File

@@ -5,14 +5,15 @@ using RBeatTime = Cryville.Crtr.BeatTime;
namespace Cryville.Crtr { namespace Cryville.Crtr {
public abstract class PropSrc { public abstract class PropSrc {
int _type; int _type;
byte[] _buf = null; protected byte[] buf = null;
public virtual void Invalidate() { _buf = null; } protected virtual bool Invalidated { get { return buf == null; } }
public virtual void Invalidate() { buf = null; }
public void Get(out int type, out byte[] value) { public void Get(out int type, out byte[] value) {
if (_buf == null) InternalGet(out _type, out _buf); if (Invalidated) _type = InternalGet();
type = _type; type = _type;
value = _buf; value = buf;
} }
protected abstract void InternalGet(out int type, out byte[] value); protected abstract int InternalGet();
public class Arbitrary : PropSrc { public class Arbitrary : PropSrc {
public int Type { get; private set; } public int Type { get; private set; }
readonly byte[] _value; readonly byte[] _value;
@@ -20,65 +21,75 @@ namespace Cryville.Crtr {
Type = type; Type = type;
_value = value; _value = value;
} }
protected override void InternalGet(out int type, out byte[] value) { protected override int InternalGet() {
type = Type; buf = _value;
value = _value; return Type;
} }
} }
public class Boolean : PropSrc { public class Boolean : PropSrc {
readonly Func<bool> _cb; readonly Func<bool> _cb;
public Boolean(Func<bool> cb) { _cb = cb; } bool m_invalidated = true;
protected override void InternalGet(out int type, out byte[] value) { protected override bool Invalidated { get { return m_invalidated; } }
type = PdtInternalType.Number; public override void Invalidate() { m_invalidated = true; }
value = new byte[] { _cb() ? (byte)1 : (byte)0, 0, 0, 0 }; public Boolean(Func<bool> cb) { _cb = cb; buf = new byte[4]; }
protected override int InternalGet() {
m_invalidated = false;
buf[0] = _cb() ? (byte)1 : (byte)0;
return PdtInternalType.Number;
} }
} }
public class Float : PropSrc { public class Float : PropSrc {
readonly Func<float> _cb; readonly Func<float> _cb;
public Float(Func<float> cb) { _cb = cb; } bool m_invalidated = true;
protected override void InternalGet(out int type, out byte[] value) { protected override bool Invalidated { get { return m_invalidated; } }
type = PdtInternalType.Number; public override void Invalidate() { m_invalidated = true; }
value = BitConverter.GetBytes(_cb()); public Float(Func<float> cb) { _cb = cb; buf = new byte[4]; }
protected override unsafe int InternalGet() {
m_invalidated = false;
fixed (byte* _ptr = buf) {
*(float*)_ptr = _cb();
}
return PdtInternalType.Number;
} }
} }
public class String : PropSrc { public class String : PropSrc {
readonly Func<string> _cb; readonly Func<string> _cb;
public String(Func<string> cb) { _cb = cb; } public String(Func<string> cb) { _cb = cb; }
protected override unsafe void InternalGet(out int type, out byte[] value) { protected override unsafe int InternalGet() {
type = PdtInternalType.String;
var v = _cb(); var v = _cb();
int strlen = v.Length; int strlen = v.Length;
value = new byte[strlen * sizeof(char) + sizeof(int)]; buf = new byte[strlen * sizeof(char) + sizeof(int)];
fixed (byte* _ptr = value) { fixed (byte* _ptr = buf) {
char* ptr = (char*)(_ptr + sizeof(int)); char* ptr = (char*)(_ptr + sizeof(int));
*(int*)_ptr = strlen; *(int*)_ptr = strlen;
int i = 0; int i = 0;
foreach (var c in v) ptr[i++] = c; foreach (var c in v) ptr[i++] = c;
} }
return PdtInternalType.String;
} }
} }
public class Identifier : PropSrc { public class Identifier : PropSrc {
readonly Func<int> _cb; readonly Func<int> _cb;
public Identifier(Func<int> cb) { _cb = cb; } public Identifier(Func<int> cb) { _cb = cb; }
protected override void InternalGet(out int type, out byte[] value) { protected override int InternalGet() {
type = PdtInternalType.Undefined; buf = BitConverter.GetBytes(_cb());
value = BitConverter.GetBytes(_cb()); return PdtInternalType.Undefined;
} }
} }
public class BeatTime : PropSrc { public class BeatTime : PropSrc {
readonly Func<RBeatTime> _cb; readonly Func<RBeatTime> _cb;
public BeatTime(Func<RBeatTime> cb) { _cb = cb; } public BeatTime(Func<RBeatTime> cb) { _cb = cb; }
protected override unsafe void InternalGet(out int type, out byte[] value) { protected override unsafe int InternalGet() {
var bt = _cb(); var bt = _cb();
type = PdtInternalType.Vector; buf = new byte[4 * sizeof(int)];
value = new byte[4 * sizeof(int)]; fixed (byte* _ptr = buf) {
fixed (byte* _ptr = value) {
int* ptr = (int*)_ptr; int* ptr = (int*)_ptr;
*ptr++ = bt.b; *ptr++ = bt.b;
*ptr++ = bt.n; *ptr++ = bt.n;
*ptr++ = bt.d; *ptr++ = bt.d;
*ptr++ = PdtInternalType.Number; *ptr++ = PdtInternalType.Number;
} }
return PdtInternalType.Vector;
} }
} }
} }