Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitebf1fb0

Browse files
author
dse
committed
Python string to CLR string marshaling cache added.
1 parente9e9051 commitebf1fb0

9 files changed

+531
-5
lines changed

‎src/runtime/Python.Runtime.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@
7676
<ReferenceInclude="System" />
7777
</ItemGroup>
7878
<ItemGroup>
79+
<CompileInclude="perf_utils\EncodedStringsFifoDictionary.cs" />
80+
<CompileInclude="perf_utils\EncodingGetStringPolyfill.cs" />
81+
<CompileInclude="perf_utils\FifoDictionary.cs" />
82+
<CompileInclude="perf_utils\RawImmutableMemBlock.cs" />
83+
<CompileInclude="perf_utils\RawMemoryFifoDictionary.cs" />
84+
<CompileInclude="perf_utils\RawMemUtils.cs" />
7985
<CompileInclude="Properties\AssemblyInfo.cs" />
8086
<CompileInclude="..\SharedAssemblyInfo.cs">
8187
<Link>Properties\SharedAssemblyInfo.cs</Link>
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
usingSystem;
2+
3+
namespacePython.Runtime
4+
{
5+
usingSystem.Runtime.InteropServices;
6+
7+
publicclassEncodedStringsFifoDictionary:IDisposable
8+
{
9+
privatereadonlyFifoDictionary<string,IntPtr>_innerDictionary;
10+
11+
privatereadonlyIntPtr_rawMemory;
12+
13+
privatereadonlyint_allocatedSize;
14+
15+
publicEncodedStringsFifoDictionary(intcapacity,intmaxItemSize)
16+
{
17+
if(maxItemSize<1)
18+
{
19+
thrownewArgumentOutOfRangeException(
20+
nameof(maxItemSize),
21+
"Maximum item size should be non-zero positive.");
22+
}
23+
24+
_innerDictionary=newFifoDictionary<string,IntPtr>(capacity);
25+
_allocatedSize=maxItemSize*capacity;
26+
_rawMemory=Marshal.AllocHGlobal(_allocatedSize);
27+
28+
MaxItemSize=maxItemSize;
29+
}
30+
31+
publicintMaxItemSize{get;}
32+
33+
publicboolTryGetValue(stringkey,outIntPtrvalue)
34+
{
35+
return_innerDictionary.TryGetValue(key,outvalue);
36+
}
37+
38+
publicIntPtrAddUnsafe(stringkey)
39+
{
40+
intnextSlot=_innerDictionary.NextSlotToAdd;
41+
IntPtrptr=_rawMemory+(MaxItemSize*nextSlot);
42+
_innerDictionary.AddUnsafe(key,ptr);
43+
returnptr;
44+
}
45+
46+
publicboolIsKnownPtr(IntPtrptr)
47+
{
48+
varuptr=(ulong)ptr;
49+
varumem=(ulong)_rawMemory;
50+
51+
returnuptr>=umem&&uptr<umem+(ulong)_allocatedSize;
52+
}
53+
54+
privatevoidReleaseUnmanagedResources()
55+
{
56+
if(_rawMemory!=IntPtr.Zero)
57+
{
58+
Marshal.FreeHGlobal(_rawMemory);
59+
}
60+
}
61+
62+
publicvoidDispose()
63+
{
64+
ReleaseUnmanagedResources();
65+
GC.SuppressFinalize(this);
66+
}
67+
68+
~EncodedStringsFifoDictionary()
69+
{
70+
ReleaseUnmanagedResources();
71+
}
72+
}
73+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
usingSystem;
2+
usingSystem.Collections.Generic;
3+
usingSystem.Reflection;
4+
usingSystem.Runtime.InteropServices;
5+
usingSystem.Text;
6+
7+
namespacePython.Runtime
8+
{
9+
/// <summary>
10+
/// This polyfill is thread unsafe.
11+
/// </summary>
12+
#if!NETSTANDARD
13+
publicstaticclassEncodingGetStringPolyfill
14+
{
15+
privatestaticreadonlyMethodInfoPlatformGetStringMethodInfo=
16+
typeof(Encoding).GetMethod(
17+
"GetString",
18+
BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic,null,
19+
new[]
20+
{
21+
typeof(byte*),typeof(int)
22+
},null);
23+
24+
privatestaticreadonlybyte[]StdDecodeBuffer=PlatformGetStringMethodInfo==null?newbyte[1024*1024]:null;
25+
26+
privatestaticDictionary<Encoding,EncodingGetStringUnsafeDelegate>PlatformGetStringMethodsDelegatesCache=newDictionary<Encoding,EncodingGetStringUnsafeDelegate>();
27+
28+
privateunsafedelegatestringEncodingGetStringUnsafeDelegate(byte*pstr,intsize);
29+
30+
publicunsafestaticstringGetString(thisEncodingencoding,byte*pstr,intsize)
31+
{
32+
if(PlatformGetStringMethodInfo!=null)
33+
{
34+
EncodingGetStringUnsafeDelegategetStringDelegate;
35+
if(!PlatformGetStringMethodsDelegatesCache.TryGetValue(encoding,outgetStringDelegate))
36+
{
37+
getStringDelegate=
38+
(EncodingGetStringUnsafeDelegate)PlatformGetStringMethodInfo.CreateDelegate(
39+
typeof(EncodingGetStringUnsafeDelegate),encoding);
40+
PlatformGetStringMethodsDelegatesCache.Add(encoding,getStringDelegate);
41+
}
42+
returngetStringDelegate(pstr,size);
43+
}
44+
45+
byte[]buffer=size<=StdDecodeBuffer.Length?StdDecodeBuffer:newbyte[size];
46+
Marshal.Copy((IntPtr)pstr,buffer,0,size);
47+
returnencoding.GetString(buffer,0,size);
48+
}
49+
}
50+
#endif
51+
52+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
usingSystem;
2+
3+
namespacePython.Runtime
4+
{
5+
usingSystem.Collections.Generic;
6+
7+
publicclassFifoDictionary<TKey,TValue>
8+
{
9+
privatereadonlyDictionary<TKey,int>_innerDictionary;
10+
11+
privatereadonlyKeyValuePair<TKey,TValue>[]_fifoList;
12+
13+
privatebool_hasEmptySlots=true;
14+
15+
publicFifoDictionary(intcapacity)
16+
{
17+
if(capacity<=0)
18+
{
19+
thrownewArgumentOutOfRangeException(nameof(capacity),"Capacity should be non-zero positive.");
20+
}
21+
22+
_innerDictionary=newDictionary<TKey,int>(capacity);
23+
_fifoList=newKeyValuePair<TKey,TValue>[capacity];
24+
25+
Capacity=capacity;
26+
}
27+
28+
publicboolTryGetValue(TKeykey,outTValuevalue)
29+
{
30+
intindex;
31+
if(_innerDictionary.TryGetValue(key,outindex))
32+
{
33+
value=_fifoList[index].Value;
34+
returntrue;
35+
}
36+
37+
value=default(TValue);
38+
returnfalse;
39+
}
40+
41+
publicvoidAddUnsafe(TKeykey,TValuevalue)
42+
{
43+
if(!_hasEmptySlots)
44+
{
45+
_innerDictionary.Remove(_fifoList[NextSlotToAdd].Key);
46+
}
47+
48+
_innerDictionary.Add(key,NextSlotToAdd);
49+
_fifoList[NextSlotToAdd]=newKeyValuePair<TKey,TValue>(key,value);
50+
51+
NextSlotToAdd++;
52+
if(NextSlotToAdd>=Capacity)
53+
{
54+
_hasEmptySlots=false;
55+
NextSlotToAdd=0;
56+
}
57+
}
58+
59+
publicintNextSlotToAdd{get;privateset;}
60+
publicintCapacity{get;}
61+
}
62+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
namespacePython.Runtime
2+
{
3+
usingSystem;
4+
5+
publicstructRawImmutableMemBlock:IEquatable<RawImmutableMemBlock>
6+
{
7+
privatereadonlyint_hash;
8+
9+
publicRawImmutableMemBlock(IntPtrptr,intsize)
10+
{
11+
if(ptr==IntPtr.Zero)
12+
{
13+
thrownewArgumentException("Memory pointer should not be zero",nameof(ptr));
14+
}
15+
16+
if(size<0)
17+
{
18+
thrownewArgumentOutOfRangeException(nameof(size),"Size should be zero or positive.");
19+
}
20+
21+
Ptr=ptr;
22+
Size=size;
23+
_hash=RawMemUtils.FastXorHash(ptr,size);
24+
}
25+
26+
publicRawImmutableMemBlock(RawImmutableMemBlockmemBlock,IntPtrnewPtr)
27+
{
28+
if(memBlock.Ptr==IntPtr.Zero)
29+
{
30+
thrownewArgumentException("Cannot copy non initialized RawImmutableMemBlock structure.",nameof(memBlock));
31+
}
32+
33+
if(newPtr==IntPtr.Zero)
34+
{
35+
thrownewArgumentException("Cannot copy to zero pointer.");
36+
}
37+
38+
RawMemUtils.CopyMemBlocks(memBlock.Ptr,newPtr,memBlock.Size);
39+
Ptr=newPtr;
40+
Size=memBlock.Size;
41+
_hash=memBlock._hash;
42+
}
43+
44+
publicIntPtrPtr{get;}
45+
46+
publicintSize{get;}
47+
48+
publicboolEquals(RawImmutableMemBlockother)
49+
{
50+
boolpreEqual=_hash==other._hash&&Size==other.Size;
51+
if(!preEqual)
52+
{
53+
returnfalse;
54+
}
55+
56+
returnRawMemUtils.CompareMemBlocks(Ptr,other.Ptr,Size);
57+
}
58+
59+
/// <inheritdoc/>
60+
publicoverrideboolEquals(objectobj)
61+
{
62+
returnobjisRawImmutableMemBlock&&Equals((RawImmutableMemBlock)obj);
63+
}
64+
65+
/// <inheritdoc/>
66+
publicoverrideintGetHashCode()
67+
{
68+
unchecked
69+
{
70+
return(_hash*397)^Size;
71+
}
72+
}
73+
74+
publicstaticbooloperator==(RawImmutableMemBlockleft,RawImmutableMemBlockright)
75+
{
76+
returnleft.Equals(right);
77+
}
78+
79+
publicstaticbooloperator!=(RawImmutableMemBlockleft,RawImmutableMemBlockright)
80+
{
81+
return!left.Equals(right);
82+
}
83+
}
84+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp