Skip to content

[Java.Interop] ReadOnlyProperty<T>? #1249

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions tests/Java.Interop-PerformanceTests/Java.Interop/JavaTiming.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Threading;

using Java.Interop;
using Java.Interop.GenericMarshaler;
Expand Down Expand Up @@ -36,6 +37,49 @@ public unsafe JavaTiming ()
Construct (ref peer, JniObjectReferenceOptions.CopyAndDispose);
}

public static int StaticReadonlyField_NoCache {
get {
const string __id = "STATIC_READONLY_FIELD.I";
var __v = _members.StaticFields.GetInt32Value (__id);
return __v;
}
}

static int? _StaticReadonlyField_Cache;
public static int StaticReadonlyField_ThreadUnsafeCache {
get {
if (_StaticReadonlyField_Cache.HasValue)
return _StaticReadonlyField_Cache.Value;
const string __id = "STATIC_READONLY_FIELD.I";
var __v = _members.StaticFields.GetInt32Value (__id);
return (int) (_StaticReadonlyField_Cache = __v);
}
}
static int _StaticReadonlyField_haveValue;
static int _StaticReadonlyField_value;

public static int StaticReadonlyField_ThreadSafeCache {
get {
if (1 == Interlocked.CompareExchange (ref _StaticReadonlyField_haveValue, 1, 0))
return _StaticReadonlyField_value;
const string __id = "STATIC_READONLY_FIELD.I";
var __v = _members.StaticFields.GetInt32Value (__id);
return _StaticReadonlyField_value = __v;
}
}

static ReadOnlyProperty<int> _rop_StaticReadonlyField = new ReadOnlyProperty<int> ();
public static unsafe int StaticReadonlyField_Rop {
get {
static int _GetInt32Value ()
{
return _members.StaticFields.GetInt32Value ("STATIC_READONLY_FIELD.I");
}
delegate *managed <int> c = &_GetInt32Value;
return _rop_StaticReadonlyField.GetValue (c);
}
}

static JniMethodInfo svm;
public static void StaticVoidMethod ()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;

using Java.Interop;

using NUnit.Framework;

namespace Java.Interop.PerformanceTests {


[TestFixture]
class ReadOnlyPropertyTiming : Java.InteropTests.JavaVMFixture {
[Test]
public void StaticReadOnlyPropertyTiming ()
{
const int count = 1000;

var noCache = Stopwatch.StartNew ();
for (int i = 0; i < count; ++i) {
_ = JavaTiming.StaticReadonlyField_NoCache;
}
noCache.Stop ();

var badCache = Stopwatch.StartNew ();
for (int i = 0; i < count; ++i) {
_ = JavaTiming.StaticReadonlyField_ThreadUnsafeCache;
}
badCache.Stop ();

var goodCache = Stopwatch.StartNew ();
for (int i = 0; i < count; ++i) {
_ = JavaTiming.StaticReadonlyField_ThreadSafeCache;
}
goodCache.Stop ();

var ropCache = Stopwatch.StartNew ();
for (int i = 0; i < count; ++i) {
_ = JavaTiming.StaticReadonlyField_Rop;
}
ropCache.Stop ();

Console.WriteLine ("Static ReadOnly Property Lookup + Invoke Timing:");
Console.WriteLine ("\t No caching: {0}, {1} ticks", noCache.Elapsed, noCache.ElapsedTicks / count);
Console.WriteLine ("\t Thread Unsafe Cache: {0}, {1} ticks", badCache.Elapsed, badCache.ElapsedTicks / count);
Console.WriteLine ("\t Thread-Safe Cache: {0}, {1} ticks", goodCache.Elapsed, goodCache.ElapsedTicks / count);
Console.WriteLine ("\tReadOnlyProperty<int> Cache: {0}, {1} ticks", ropCache.Elapsed, ropCache.ElapsedTicks / count);
}
}

struct ReadOnlyProperty<T> {
int have_value;
T value;

[MethodImpl (MethodImplOptions.AggressiveInlining)]
public unsafe T GetValue (delegate *<T> c)
{
if (1 == Interlocked.CompareExchange (ref have_value, 1, 0))
return value;
var __v = c ();
value = __v;
return __v;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

public class JavaTiming {

public static final int STATIC_READONLY_FIELD = getStaticReadonlyFieldValue ();

static int getStaticReadonlyFieldValue ()
{
return 42;
}

public static void StaticVoidMethod ()
{
}
Expand Down