Skip to content

Instantly share code, notes, and snippets.

@pCYSl5EDgo
Last active January 18, 2023 21:41
Show Gist options
  • Save pCYSl5EDgo/13ee0a5923f1dbfdec44a25904adb8ef to your computer and use it in GitHub Desktop.
Save pCYSl5EDgo/13ee0a5923f1dbfdec44a25904adb8ef to your computer and use it in GitHub Desktop.
using System;
using System.Diagnostics;
using NUnit.Framework;
using UnityEngine;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
namespace Tests
{
public unsafe class UnsafeUtilityTests
{
Stopwatch watch;
[SetUp]
public void SetUp()
{
watch = new Stopwatch();
}
[Test]
public void AddressOfTest()
{
var xs = stackalloc int[1024];
var _0 = new IntPtr(UnsafeUtility.AddressOf(ref xs[0]));
var _256 = new IntPtr(UnsafeUtility.AddressOf(ref xs[256]));
UnityEngine.Debug.Log(_0.ToInt64()); // 13865367520
UnityEngine.Debug.Log(_256.ToInt64()); // 13865368544
}
[Test]
public void AddressOfSpeedTest()
{
var array = new Guid[1024];
Guid* _0, _256;
const int COUNT = 100000;
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
{
fixed (Guid* ptr = &array[0])
{
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
_0 = ptr + 0;
_256 = ptr + 256;
}
}
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
{
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
}
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
}
[Test]
public void AddressOfSpeed_OftenFix_Test()
{
var array = new Guid[1024];
Guid* _0, _256;
const int COUNT = 10000000;
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
{
fixed (Guid* ptr = array)
{
_0 = ptr + 0;
_256 = ptr + 256;
}
}
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
{
fixed (Guid* ptr = &array[0])
{
_0 = ptr + 0;
_256 = ptr + 256;
}
}
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
{
_0 = (Guid*)UnsafeUtility.AddressOf(ref array[0]);
_256 = (Guid*)UnsafeUtility.AddressOf(ref array[256]);
}
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
}
[Test]
public void CopyObjectAddressToPtrTest()
{
var guid = (object)(Guid.NewGuid());
Guid* ptr = (Guid*)UnsafeUtility.Malloc(sizeof(Guid), 4, Allocator.Temp);
UnsafeUtility.CopyObjectAddressToPtr(guid, ptr);
UnityEngine.Debug.Log(ptr->ToString());
UnsafeUtility.Free(ptr, Allocator.Temp);
}
[Test]
public void CopyObjectAddressToPtrSpeedTest()
{
const int COUNT = 100000;
var array = new object[1024];
var ptr = (Guid*)UnsafeUtility.Malloc(sizeof(Guid), 4, Allocator.Temp);
for (int i = 0; i < array.Length; i++)
array[i] = Guid.NewGuid();
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
{
for (int j = 0; j < array.Length; j++)
{
UnsafeUtility.CopyObjectAddressToPtr(array[j], ptr);
}
}
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
{
for (int j = 0; j < array.Length; j++)
{
*ptr = (Guid)array[j];
}
}
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
UnsafeUtility.Free(ptr, Allocator.Temp);
}
[Test]
public void CopyPtrToStructureSpeedTest()
{
const int COUNT = 100000;
Guid* ptr = stackalloc Guid[1024];
Guid id;
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
{
for (int j = 0; j < 1024; j++)
{
id = ptr[j];
}
}
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
{
for (int j = 0; j < 1024; j++)
{
UnsafeUtility.CopyPtrToStructure(ptr + j, out id);
}
}
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
}
[Test]
public void CopyStructureToPtrSpeedTest()
{
const int COUNT = 100000;
var id = Guid.NewGuid();
var ptr = stackalloc Guid[1024];
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
{
for (int j = 0; j < 1024; j++)
{
ptr[j] = id;
}
}
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
{
for (int j = 0; j < 1024; j++)
{
UnsafeUtility.CopyStructureToPtr(ref id, ptr + j);
}
}
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
}
[Test]
public void EnumToIntSpeedTest()
{
const int COUNT = 100000;
var enums = stackalloc AttributeTargets[] { AttributeTargets.All, AttributeTargets.Assembly, AttributeTargets.Class, AttributeTargets.Constructor, AttributeTargets.Delegate, AttributeTargets.Enum, AttributeTargets.Event, AttributeTargets.Field, AttributeTargets.GenericParameter, AttributeTargets.Interface, AttributeTargets.Method, AttributeTargets.Module, AttributeTargets.Parameter, AttributeTargets.Property, AttributeTargets.ReturnValue, AttributeTargets.Struct, };
var array = stackalloc int[16];
watch.Start();
for (int i = 0; i < COUNT; i++)
for (int j = 0; j < 16; j++)
array[j] = (int)enums[j];
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
for (int j = 0; j < 16; j++)
array[j] = Conv0(enums[j]);
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
for (int j = 0; j < 16; j++)
array[j] = Conv1(enums[j]);
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
for (int j = 0; j < 16; j++)
array[j] = Conv2(enums[j]);
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
for (int j = 0; j < 16; j++)
array[j] = Conv3(enums[j]);
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
for (int j = 0; j < 16; j++)
array[j] = UnsafeUtility.EnumToInt(enums[j]);
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
}
private static int Conv0<T>(T val) where T : Enum => (int)(object)val;
private static int Conv1<T>(T val) where T : struct => (int)(object)val;
private static int Conv2<T>(T val) where T : Enum => Convert.ToInt32(val);
private static int Conv3<T>(T val) where T : struct, IConvertible => val.ToInt32(null);
[Test]
public void GetFieldOffsetSpeedTest()
{
var t = typeof(ValueTuple<Guid, Guid, Guid, Guid>);
const int COUNT = 1000000;
var fieldInfo = t.GetField("Item3");
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
System.Runtime.InteropServices.Marshal.OffsetOf<ValueTuple<Guid, Guid, Guid, Guid>>("Item3");
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
System.Runtime.InteropServices.Marshal.OffsetOf(t, "Item3");
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
UnsafeUtility.GetFieldOffset(fieldInfo);
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
}
[Test]
public void IsValidAllocatorTest()
{
foreach (var e in Enum.GetValues(typeof(Allocator)))
{
UnityEngine.Debug.Log(e.ToString() + " : " + UnsafeUtility.IsValidAllocator((Allocator)e));
}
}
[Test]
public void IsValidAllocatorSpeedTest()
{
const int COUNT = 100000000;
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
{
UnsafeUtility.IsValidAllocator(Allocator.Temp);
UnsafeUtility.IsValidAllocator(Allocator.Persistent);
}
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
{
IsValid(Allocator.Temp);
IsValid(Allocator.Persistent);
}
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
}
private static bool IsValid(Allocator allocator)
{
switch (allocator)
{
case Allocator.Invalid:
case Allocator.None:
return false;
default:
return true;
}
}
[Test]
public void MallocFreeSpeedTest()
{
const int COUNT = 160000;
const int SIZE = 1 << 14;
var ptrs = (void**)UnsafeUtility.Malloc(sizeof(void*) * COUNT, 4, Allocator.Temp);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
ptrs[i] = UnsafeUtility.Malloc(SIZE, 4, Allocator.Temp);
watch.Stop();
UnityEngine.Debug.Log(nameof(Allocator.Temp) + " : " + watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
UnsafeUtility.Free(ptrs[i], Allocator.Temp);
watch.Stop();
UnityEngine.Debug.Log(nameof(Allocator.Temp) + " : " + watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
ptrs[i] = UnsafeUtility.Malloc(SIZE, 4, Allocator.TempJob);
watch.Stop();
UnityEngine.Debug.Log(nameof(Allocator.TempJob) + " : " + watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
UnsafeUtility.Free(ptrs[i], Allocator.TempJob);
watch.Stop();
UnityEngine.Debug.Log(nameof(Allocator.TempJob) + " : " + watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
ptrs[i] = UnsafeUtility.Malloc(SIZE, 4, Allocator.Persistent);
watch.Stop();
UnityEngine.Debug.Log(nameof(Allocator.Persistent) + " : " + watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
UnsafeUtility.Free(ptrs[i], Allocator.Persistent);
watch.Stop();
UnityEngine.Debug.Log(nameof(Allocator.Persistent) + " : " + watch.ElapsedMilliseconds);
UnsafeUtility.Free(ptrs, Allocator.Temp);
var ptrs2 = (IntPtr*)UnsafeUtility.Malloc(sizeof(IntPtr) * COUNT, 4, Allocator.Temp);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
ptrs2[i] = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(SIZE);
watch.Stop();
UnityEngine.Debug.Log(nameof(System.Runtime.InteropServices.Marshal.AllocCoTaskMem) + " : " + watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
System.Runtime.InteropServices.Marshal.FreeCoTaskMem(ptrs2[i]);
watch.Stop();
UnityEngine.Debug.Log(nameof(System.Runtime.InteropServices.Marshal.FreeCoTaskMem) + " : " + watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
ptrs2[i] = System.Runtime.InteropServices.Marshal.AllocHGlobal(SIZE);
watch.Stop();
UnityEngine.Debug.Log(nameof(System.Runtime.InteropServices.Marshal.AllocHGlobal) + " : " + watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
System.Runtime.InteropServices.Marshal.FreeHGlobal(ptrs2[i]);
watch.Stop();
UnityEngine.Debug.Log(nameof(System.Runtime.InteropServices.Marshal.FreeHGlobal) + " : " + watch.ElapsedMilliseconds);
UnsafeUtility.Free(ptrs2, Allocator.Temp);
}
[Test]
public void MemClearSpeedTest()
{
var array = new Guid[1024];
const int COUNT = 1000000;
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
Array.Clear(array, 0, array.Length);
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
fixed (void* ptr = &array[0])
{
watch.Start();
for (int i = 0; i < COUNT; i++)
for (int j = 0; j < 1024; j++)
array[j] = default;
watch.Stop();
}
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
fixed (void* ptr = &array[0])
{
watch.Start();
for (int i = 0; i < COUNT; i++)
UnsafeUtility.MemClear(ptr, sizeof(Guid) << 10);
watch.Stop();
}
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
}
[Test]
public void MemCpySpeedTest()
{
const int COUNT = 1 << 10;
const int size = 1 << 18;
var ptr = stackalloc byte[size];
var ptr2 = stackalloc byte[size];
var p = (long*)ptr;
var p2 = (long*)ptr2;
watch.Reset();
watch.Start();
const int V = size >> 3;
for (int i = 0; i < COUNT; i++)
for (int j = 0; j < V; j++)
p[j] = p2[j];
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
for (int j = 0; j < size; j++)
ptr[j] = ptr2[j];
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
Buffer.MemoryCopy(ptr, ptr2, size, size);
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
UnsafeUtility.MemCpy(ptr2, ptr, size);
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
}
[Test]
public void MemCpyReplicateSpeedTest()
{
const int LOOP_COUNT = 1 << 10;
const int COUNT = 1 << 14;
var ptr = stackalloc Guid[COUNT];
var id = Guid.NewGuid();
var idptr = &id;
watch.Reset();
watch.Start();
for (int i = 0; i < LOOP_COUNT; i++)
for (int j = 0; j < COUNT; j++)
ptr[j] = id;
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < LOOP_COUNT; i++)
for (int j = 0; j < COUNT; j++)
UnsafeUtility.MemCpy(ptr + j, idptr, sizeof(Guid));
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < LOOP_COUNT; i++)
UnsafeUtility.MemCpyReplicate(ptr, idptr, sizeof(Guid), COUNT);
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
}
struct Stride0
{
public Guid X, Y, Z, W;
public long A, B, C, D, E, F, G, H;
}
[Test]
public void MemCpyStrideTest()
{
const int COUNT = 1 << 16;
const int size = 1 << 10;
var dest = stackalloc Guid[size];
var src = stackalloc Stride0[size];
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
for (int j = 0; j < size; j++)
dest[j] = src[j].X;
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
// Stride0のフィールド X を destにコピペする
UnsafeUtility.MemCpyStride(dest, sizeof(Guid), src, sizeof(Stride0), sizeof(Guid), size);
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
}
[Test]
public void PinSpeedTest()
{
const int COUNT = 1 << 20;
var array = new Guid[1 << 10];
var intptrs = (System.Runtime.InteropServices.GCHandle*)UnsafeUtility.Malloc(sizeof(System.Runtime.InteropServices.GCHandle) * COUNT, 4, Allocator.Temp);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
intptrs[i] = System.Runtime.InteropServices.GCHandle.Alloc(array, System.Runtime.InteropServices.GCHandleType.Pinned);
watch.Stop();
UnityEngine.Debug.Log("GCHandle.Alloc : " + watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
intptrs[i].Free();
watch.Stop();
UnityEngine.Debug.Log("GCHandle.Free : " + watch.ElapsedMilliseconds);
UnsafeUtility.Free(intptrs, Allocator.Temp);
var ptrs = (void**)UnsafeUtility.Malloc(sizeof(void*) * COUNT, 4, Allocator.Temp);
var handles = (ulong*)UnsafeUtility.Malloc(sizeof(ulong) * COUNT, 4, Allocator.Temp);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
ptrs[i] = UnsafeUtility.PinGCArrayAndGetDataAddress(array, out handles[i]);
watch.Stop();
UnityEngine.Debug.Log("PinGCArrayAndGetDataAddress : " + watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
UnsafeUtility.ReleaseGCObject(handles[i]);
watch.Stop();
UnityEngine.Debug.Log("ReleaseGCObject : " + watch.ElapsedMilliseconds);
UnsafeUtility.Free(handles, Allocator.Temp);
UnsafeUtility.Free(ptrs, Allocator.Temp);
}
[Test]
public void ReadWriteArrayElementSpeedTest()
{
const int COUNT = 1 << 30;
const int size = 1 << 10;
var array = stackalloc int[size];
var array2 = stackalloc ReadWrite0[size];
int x = 0;
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
x = array[16];
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
x = UnsafeUtility.ReadArrayElement<int>(array, 16);
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
x = array2[16].a;
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
x = UnsafeUtility.ReadArrayElementWithStride<int>(array2, 16, sizeof(ReadWrite0));
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
array[16] = x;
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
UnsafeUtility.WriteArrayElement(array, 16, x);
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
array2[16].a = x;
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
for (int i = 0; i < COUNT; i++)
UnsafeUtility.WriteArrayElementWithStride<int>(array2, 16, sizeof(ReadWrite0), x);
watch.Stop();
UnityEngine.Debug.Log(watch.ElapsedMilliseconds);
}
struct ReadWrite0
{
public int a, b, c, d, e, f, g, h;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment