[Unity 소프트 광고 2019] UniEnumExtension에서 500배속 열거형 처리[Mono. Cecil]
18790 단어 Mono.Cecil흑마법UnityC#
이 글은 유니티 말랑말랑 여름 이벤트 달력 2019 19일째 되는 글입니다.
며칠 전 17일 보도는 @nanaki_pg 씨의 Oculus 가속도 센서를 사용하여 VR 공간에서 이동!
전날 18일 보도는 @mao_ 씨의 "!
다음 날인 20일 보도는 @kingyo222 씨의'Unity: UI Elements로 샘플 몇 개 썼어요!'입니다!
다음 날인 21일 보도는 @yKimisaki 씨의'UIELEMENTS도 UniRx를 사용하고 싶어요.'입니다!
입문
UniEnumExtension은Booth과GitHub에 공개된 편집기 확장 자산입니다.
"UniEnumExtension"을 가져오면 매거진 ToString은 원본 소스 코드를 바꾸지 않고 약 500배에서 100배 이상의 속도를 낼 수 있습니다.
버전 정보 등
배포 방법
Git 설치
먼저 새 프로젝트를 만듭니다.
Packages 폴더는 초기에 Analystic Library와 Package Manager UI 등을 포함합니다.
그리고 명령 프롬프트와 터미널 등을 시작합니다.
대상 항목 아래의 포장 폴더로 이동하십시오.
git clone https://github.com/pCYSl5EDgo/UniEnumExtension
의 명령.
아래의 표시일 것이다.
유니티 편집기로 돌아가 봅시다.새로운 UniEnumExtension 및 MonoCecil이 늘었을 거예요.
설치는 여기서 끝냅니다.간단하네!
Booth에서 구입 시
다운로드한 zip 파일을 현장에서 압축을 풀다.
UniEnumExtension.유니티 패키지 파일이 나타날 수 있으므로 드래그 앤 드롭 등을 통해 프로젝트로 가져오십시오.
라이센스 - jp 즉 개발자는 전원을 편집기로 확장하고 컴퓨터마다 하나의 사용과 양도와 재발포 금지 등을 규정했다.
Assets/Plugins/UniEnumExtensionInstaller는 GitHub에서 UniEnumExtension만 설치하는 설치 프로그램입니다.
Packages/UniEnumExtension이 확인되면 삭제할 수 있습니다.
사용 방법
아무것도 하지 않아도 열거형의 성능이 좋아진다.
...이러면 해설이 외롭기 때문에 좀 더 구체적으로.메뉴에서 [윈도우] > [UniEnumExtension]을 클릭하면 다음 창이 열립니다.
ProcessRewriteToString All Assemblies가 선택되었지만 이 옵션을 선택하면 모든 Player 구축의 asmdef를 처리합니다.
우리 체크를 떼어 봅시다.
UniEnumExtension은 컴파일 시간을 처리할 수량에 비례하여 증가시킵니다.열거 유형이 없는 구성 요소를 제외하면 처리 시간이 단축됩니다.
수동으로 측정한 부품당 0.05~0.2초 정도의 처리 시간이 걸렸습니다.
왜 이 자산이 필요합니까?
Enums.NET.
아무것도 하지 않아도 열거형의 성능이 좋아진다.
...이러면 해설이 외롭기 때문에 좀 더 구체적으로.메뉴에서 [윈도우] > [UniEnumExtension]을 클릭하면 다음 창이 열립니다.
ProcessRewriteToString All Assemblies가 선택되었지만 이 옵션을 선택하면 모든 Player 구축의 asmdef를 처리합니다.
우리 체크를 떼어 봅시다.
UniEnumExtension은 컴파일 시간을 처리할 수량에 비례하여 증가시킵니다.열거 유형이 없는 구성 요소를 제외하면 처리 시간이 단축됩니다.
수동으로 측정한 부품당 0.05~0.2초 정도의 처리 시간이 걸렸습니다.
왜 이 자산이 필요합니까?
Enums.NET.
그 결과 ToString의 매거 속도는 표준에 비해 45배 향상되었다.
이것은 아주 좋은 일이다.
UniEnumExtension의 속도는 표준보다 300-500배 빠릅니다.
모노야.Cecil의 정적 IL 해석을 통해 후면 컴파일할 때 권투하는 방법 호출과 가상 방법 호출 등을 상수로 바꾸거나 신속하고 분배가 적은 비가상 방법 호출로 바꾸어 실현한다.
또한 완전히 다른 기능이지만 Burst Job에서 foreach를 사용할 수 있습니다!
어떤 상황에서 고속화를 진행합니까
고급 테마
Packages/UniEnumExtension/BuildPlayer/EnumExtensionPostBuildPlayerScriptDll.cs 및 Packages/UniEnumExtension/UI/Programcs를 보십시오.
EnumExtensionPostBuildPlayerScriptDll.cs는 Mono 구축 또는 IL2 CPP 구축 시 후기 프로세스 IL 편집을 수행합니다.
실현UnityEditor.Build.IPostBuildPlayerScriptDLLs의 유형은 구축할 때 자신도 모르게 실례화되어 리셋이라고 불린다.콜백은 구축에 사용되는 모든 C# 파일을 컴파일하고 DLL을 제공할 때입니다.public void OnPostBuildPlayerScriptDLLs(BuildReport report)
{
step[0] = BeginBuildStep.Invoke(report, uniEnumExtension);
try
{
Implement(report);
}
finally
{
EndBuildStep.Invoke(report, step);
}
}
리셋에는 특별한 필요가 없지만 UnityEditor.Build.Reporting.BuildReport 의 internal API Begin/EndBaildStep을 사용합니다.
공식 참고 내에 설명이 없기 때문에 구체적인 역할은 알 수 없지만 구축 시간과 오류 처리 시 정보량이 늘어날 것으로 보인다.private void Implement(BuildReport report)
{
string[] guidArray = AssetDatabase.FindAssets("t:" + nameof(ProgramStatus));
ProgramStatus programStatus = AssetDatabase.LoadAssetAtPath<ProgramStatus>(AssetDatabase.GUIDToAssetPath(guidArray[0]));
programStatus.Initialize();
IEnumerable<string> targetNames = programStatus.Enables.Zip(programStatus.OutputPaths, (enable, outputPath) => (enable, Path.GetFileName(outputPath))).ToArray();
IEnumerable<string> assemblyPaths = report.files.Where(buildFile =>
{
if (buildFile.role != "ManagedLibrary")
{
return false;
}
if (string.IsNullOrWhiteSpace(buildFile.path)) return false;
string buildName = Path.GetFileName(buildFile.path);
return targetNames.All(pair => pair.Item2 != buildName) || targetNames.First(pair => pair.Item2 == buildName).Item1;
}).Select(buildFile => buildFile.path);
string directoryName = Path.GetDirectoryName(report.files[0].path);
Debug.Log(directoryName);
using (var extender = new EnumExtender(searchDirectory: new string[1] { directoryName }))
{
extender.Extend(assemblyPaths);
}
}
단일 프로필의 스크립트 대상을 읽습니다.
그런 다음 구축 보고서의 파일 속성에서 DLL 또는 PDB 파일 목록을 얻을 수 있습니다.
이 중 role이 ManagedLibrary이고 설정되고 처리된 DLL만 IENumerableassembly Paths로 검색합니다.
EnumExtender 인스턴스에 Extend 메서드를 전달하면 해당 구성 요소에 대한 IL 개작이 수행됩니다.
EnumExtender 구조 함수는 어셈블리 참조를 해석하는 데 사용할 디렉토리 이름을 제공합니다.
어셈블리 참조 해결?이런 사람은 보세요Mono.Cecil 시작.
고급 API
using(EnumExtender extender = new EnumExtender(string[] searchDirectory))
extender.Extend(IEnumerable assemblyPaths);
문서 레지스트리에 항목을 추가합니다.
assembly Paths에서 경로를 지정하면 여러 가지 일을 잘 처리할 수 있습니다.
하위 API
EnumExtender에는 구조 함수가 하나 더 있습니다.
public EnumExtender(IModuleProcessor[] moduleProcessorCollection, ITypeProcessor[] typeProcessorCollection, IMethodProcessor[] methodProcessorCollection, string[] searchDirectories)
UniEnumExtension.IModuleProcessor, UniEnumExtension.ITypeProcessor, UniEnumExtension.IMethodProcessor는 모듈(구성 요소), 유형 및 방법을 처리하는 인터페이스입니다.
구조 함수에서 IL 처리를 등록하는 거죠.
상기 3개의 인터페이스는 공개적이기 때문에 후면 컴파일할 때 고리를 걸어 EnumExtender를 실행하는 것이 좋습니다.
EnumExtender를 비활성화해야 합니다.IL 쓰기를 완료할 수 없습니다.
EnumExtender는 UniEnumExtension입니다.IExtender를 구현했기 때문에 그 단계부터 교체하는 것도 좋습니다.public interface IExtender : IDisposable
{
void Extend(IEnumerable<string> assemblyPaths);
}
public interface IModuleProcessor : IProcessor
{
void Process(ModuleDefinition moduleDefinition);
}
public interface ITypeProcessor : IProcessor
{
void Process(ModuleDefinition systemModuleDefinition, TypeDefinition typeDefinition);
}
public interface IMethodProcessor : IProcessor
{
bool ShouldProcess(TypeDefinition typeDefinition);
void Process(ModuleDefinition systemModuleDefinition, MethodDefinition methodDefinition);
}
감상
Mono.나는 Cecil이 뒤에서 컴파일할 때 constexpr을 진행할 수 있다는 것을 느꼈다.
readonly 필드를 실현하고 IL 수준에서도 어떤 형식으로 표현할 수 있다면 정말constexpr입니다.
추가 기능 요구 사항이 있는 경우 제 트위터에 DM이 있어요. 또는 GitHub으로 Issue 만들기.
Reference
이 문제에 관하여([Unity 소프트 광고 2019] UniEnumExtension에서 500배속 열거형 처리[Mono. Cecil]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/pCYSl5EDgo/items/b181d3ef72c827560e25
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
public void OnPostBuildPlayerScriptDLLs(BuildReport report)
{
step[0] = BeginBuildStep.Invoke(report, uniEnumExtension);
try
{
Implement(report);
}
finally
{
EndBuildStep.Invoke(report, step);
}
}
private void Implement(BuildReport report)
{
string[] guidArray = AssetDatabase.FindAssets("t:" + nameof(ProgramStatus));
ProgramStatus programStatus = AssetDatabase.LoadAssetAtPath<ProgramStatus>(AssetDatabase.GUIDToAssetPath(guidArray[0]));
programStatus.Initialize();
IEnumerable<string> targetNames = programStatus.Enables.Zip(programStatus.OutputPaths, (enable, outputPath) => (enable, Path.GetFileName(outputPath))).ToArray();
IEnumerable<string> assemblyPaths = report.files.Where(buildFile =>
{
if (buildFile.role != "ManagedLibrary")
{
return false;
}
if (string.IsNullOrWhiteSpace(buildFile.path)) return false;
string buildName = Path.GetFileName(buildFile.path);
return targetNames.All(pair => pair.Item2 != buildName) || targetNames.First(pair => pair.Item2 == buildName).Item1;
}).Select(buildFile => buildFile.path);
string directoryName = Path.GetDirectoryName(report.files[0].path);
Debug.Log(directoryName);
using (var extender = new EnumExtender(searchDirectory: new string[1] { directoryName }))
{
extender.Extend(assemblyPaths);
}
}
EnumExtender 인스턴스에 Extend 메서드를 전달하면 해당 구성 요소에 대한 IL 개작이 수행됩니다.
EnumExtender 구조 함수는 어셈블리 참조를 해석하는 데 사용할 디렉토리 이름을 제공합니다.
어셈블리 참조 해결?이런 사람은 보세요Mono.Cecil 시작.
고급 API
using(EnumExtender extender = new EnumExtender(string[] searchDirectory))
extender.Extend(IEnumerable
문서 레지스트리에 항목을 추가합니다.
assembly Paths에서 경로를 지정하면 여러 가지 일을 잘 처리할 수 있습니다.
하위 API
EnumExtender에는 구조 함수가 하나 더 있습니다.
public EnumExtender(IModuleProcessor[] moduleProcessorCollection, ITypeProcessor[] typeProcessorCollection, IMethodProcessor[] methodProcessorCollection, string[] searchDirectories)
UniEnumExtension.IModuleProcessor, UniEnumExtension.ITypeProcessor, UniEnumExtension.IMethodProcessor는 모듈(구성 요소), 유형 및 방법을 처리하는 인터페이스입니다.
구조 함수에서 IL 처리를 등록하는 거죠.
상기 3개의 인터페이스는 공개적이기 때문에 후면 컴파일할 때 고리를 걸어 EnumExtender를 실행하는 것이 좋습니다.
EnumExtender를 비활성화해야 합니다.IL 쓰기를 완료할 수 없습니다.
EnumExtender는 UniEnumExtension입니다.IExtender를 구현했기 때문에 그 단계부터 교체하는 것도 좋습니다.
public interface IExtender : IDisposable
{
void Extend(IEnumerable<string> assemblyPaths);
}
public interface IModuleProcessor : IProcessor
{
void Process(ModuleDefinition moduleDefinition);
}
public interface ITypeProcessor : IProcessor
{
void Process(ModuleDefinition systemModuleDefinition, TypeDefinition typeDefinition);
}
public interface IMethodProcessor : IProcessor
{
bool ShouldProcess(TypeDefinition typeDefinition);
void Process(ModuleDefinition systemModuleDefinition, MethodDefinition methodDefinition);
}
감상
Mono.나는 Cecil이 뒤에서 컴파일할 때 constexpr을 진행할 수 있다는 것을 느꼈다.
readonly 필드를 실현하고 IL 수준에서도 어떤 형식으로 표현할 수 있다면 정말constexpr입니다.
추가 기능 요구 사항이 있는 경우 제 트위터에 DM이 있어요. 또는 GitHub으로 Issue 만들기.
Reference
이 문제에 관하여([Unity 소프트 광고 2019] UniEnumExtension에서 500배속 열거형 처리[Mono. Cecil]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/pCYSl5EDgo/items/b181d3ef72c827560e25텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)