[appcompare] Remove old/local copy of the tool and update comparison documentation (#14190)
There's a newer version of the tool availble as a (tool) [nuget](https://www.nuget.org/packages/appcompare/) The nicest part, for this use case, is that it can map renamed files between the two app bundles being compared. [Example](https://gist.github.com/spouliot/68a43a4f514315d52b35446016ba0d2e)
This commit is contained in:
Родитель
d1f8cc8a58
Коммит
e6e4ddbab2
|
@ -49,8 +49,8 @@ compare compare-size: $(TARGETS)
|
|||
$(MAKE) report
|
||||
|
||||
report:
|
||||
cd ../../tools/app-compare && dotnet run $(abspath size-comparison/MySingleView/oldnet/bin/iPhone/Release/MySingleView.app) $(abspath size-comparison/MySingleView/dotnet/bin/iPhone/Release/net6.0-ios/ios-arm64/MySingleView.app) > $(CURDIR)/report.md
|
||||
gist $(CURDIR)/report.md
|
||||
appcompare $(abspath size-comparison/MySingleView/oldnet/bin/iPhone/Release/MySingleView.app) $(abspath size-comparison/MySingleView/dotnet/bin/iPhone/Release/net6.0-ios/ios-arm64/MySingleView.app) \
|
||||
--output-markdown $(CURDIR)/report.md --gist --mapping-file $(CURDIR)/size-comparison/MySingleView.map
|
||||
|
||||
COMMON_ARGS=/p:Platform=iPhone /p:Configuration=Release
|
||||
build-oldnet:
|
||||
|
|
|
@ -2,6 +2,22 @@
|
|||
|
||||
## size-comparison
|
||||
|
||||
To install the latest `appcompare` tool do:
|
||||
|
||||
```bash
|
||||
$ dotnet tool install --global appcompare
|
||||
```
|
||||
|
||||
You can update it to the latest version by running:
|
||||
|
||||
```bash
|
||||
$ dotnet tool update --global appcompare
|
||||
```
|
||||
|
||||
The current directory might point to a different and incompatible dotnet
|
||||
SDK, resulting in an error. However running the command from a different
|
||||
location (outside the repo) should work.
|
||||
|
||||
### Easier Analysis
|
||||
|
||||
If you want to read/compare the IL inside the assemblies you need to disable IL stripping.
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
MySingleView.exe=MySingleView.dll
|
||||
Xamarin.iOS.dll=Microsoft.iOS.dll
|
||||
Xamarin.iOS.aotdata.arm64=Microsoft.iOS.aotdata.arm64
|
||||
mscorlib.aotdata.arm64=System.Private.CoreLib.aotdata.arm64
|
||||
mscorlib.dll=System.Private.CoreLib.dll
|
|
@ -1 +0,0 @@
|
|||
out
|
|
@ -1,120 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Tools {
|
||||
|
||||
public class AppComparer : DirectoryComparer
|
||||
{
|
||||
public AppComparer (string dir1, string dir2)
|
||||
{
|
||||
Directory1 = new DirectoryInfo (dir1);
|
||||
Directory2 = new DirectoryInfo (dir2);
|
||||
|
||||
app1 = dir1;
|
||||
app2 = dir2;
|
||||
}
|
||||
|
||||
string dir;
|
||||
string app1, app2;
|
||||
// stats
|
||||
long native1, native2;
|
||||
long aotdata1, aotdata2;
|
||||
long managed1, managed2;
|
||||
long total1, total2;
|
||||
|
||||
public override string GetKey (string rootedName)
|
||||
{
|
||||
var sep = rootedName.EndsWith (".aotdata") ? "!!!!!!!!!!!" : "!!!!!!!!!!!!!!!!!" ;
|
||||
return Path.GetDirectoryName (rootedName) + sep + Path.GetFileName (rootedName);
|
||||
}
|
||||
|
||||
public override void Start ()
|
||||
{
|
||||
base.Start ();
|
||||
Output.WriteLine ("# Application Comparer");
|
||||
Output.WriteLine ();
|
||||
Output.WriteLine ($"* **A** `{app1}`");
|
||||
Output.WriteLine ($"* **B** `{app2}`");
|
||||
Output.WriteLine ();
|
||||
Output.WriteLine ("| Directories / Files | A | B | diff | % |");
|
||||
Output.WriteLine ("| ------------------- | --: | --: | ---: | --: |");
|
||||
}
|
||||
|
||||
string GetSize (FileInfo info, out long length)
|
||||
{
|
||||
length = 0;
|
||||
if (info == null)
|
||||
return "0";
|
||||
if ((info.Attributes & FileAttributes.ReparsePoint) != 0)
|
||||
return "-";
|
||||
length = info.Length;
|
||||
return length.ToString ("N0");
|
||||
}
|
||||
|
||||
public override void Process (Item item)
|
||||
{
|
||||
if (item.Directory != dir) {
|
||||
dir = item.Directory;
|
||||
Output.Write ("| ./");
|
||||
Output.Write (dir);
|
||||
Output.Write (" | | | | |");
|
||||
}
|
||||
|
||||
long s1 = 0;
|
||||
long s2 = 0;
|
||||
|
||||
var d1 = GetSize (item.Info1, out s1);
|
||||
var d2 = GetSize (item.Info2, out s2);
|
||||
WriteStats (" " + item.Name, s1, s2, d1, d2);
|
||||
|
||||
switch (Path.GetExtension (item.Name)) {
|
||||
case ".aotdata":
|
||||
case ".arm64": // actually .aotdata.arm64
|
||||
aotdata1 += s1;
|
||||
aotdata2 += s2;
|
||||
break;
|
||||
case ".dll":
|
||||
case ".exe":
|
||||
managed1 += s1;
|
||||
managed2 += s2;
|
||||
break;
|
||||
case "":
|
||||
// we assume the largest file without extension is the native executable
|
||||
if (s1 > native1)
|
||||
native1 = s1;
|
||||
if (s2 > native2)
|
||||
native2 = s2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
total1 += s1;
|
||||
total2 += s2;
|
||||
}
|
||||
|
||||
void WriteStats (string name, long value1, long value2, string display1 = null, string display2 = null)
|
||||
{
|
||||
if (display1 == null)
|
||||
display1 = value1.ToString ("N0");
|
||||
if (display2 == null)
|
||||
display2 = value2.ToString ("N0");
|
||||
var percent = (value1 == 0) ? "- " : ((value2 - value1) / (double) value1).ToString ("P1");
|
||||
Output.WriteLine ($"| {name} | {display1} | {display2} | {(value2 - value1):N0} | {percent} |");
|
||||
}
|
||||
|
||||
public override void End()
|
||||
{
|
||||
Output.WriteLine ("| | | | | |");
|
||||
Output.WriteLine ("| **Statistics** | | | | |");
|
||||
Output.WriteLine ("| | | | | |");
|
||||
WriteStats ("Native subtotal", native1 + aotdata1, native2 + aotdata2);
|
||||
WriteStats (" Executable", native1, native2);
|
||||
WriteStats (" AOT data", aotdata1, aotdata2);
|
||||
Output.WriteLine ("| | | | | |");
|
||||
WriteStats ("Managed *.dll/exe", managed1, managed2);
|
||||
Output.WriteLine ("| | | | | |");
|
||||
WriteStats ("**TOTAL**", total1, total2);
|
||||
base.End ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Tools {
|
||||
|
||||
public class Item {
|
||||
public string Name { get; set; }
|
||||
public string Directory { get; set; }
|
||||
public FileInfo Info1 { get; set; }
|
||||
public FileInfo Info2 { get; set; }
|
||||
}
|
||||
|
||||
public abstract class DirectoryComparer {
|
||||
|
||||
public DirectoryComparer ()
|
||||
{
|
||||
Output = Console.Out;
|
||||
}
|
||||
|
||||
public DirectoryInfo Directory1 { get; protected set; }
|
||||
public DirectoryInfo Directory2 { get; protected set; }
|
||||
|
||||
public TextWriter Output { get; set; }
|
||||
|
||||
string GetRootName (FileInfo info, int start)
|
||||
{
|
||||
return info.FullName.Substring (start);
|
||||
}
|
||||
|
||||
public virtual string GetKey (string rootedName)
|
||||
{
|
||||
return rootedName;
|
||||
}
|
||||
|
||||
public void Compare ()
|
||||
{
|
||||
Dictionary<string,Item> items = new Dictionary<string,Item> ();
|
||||
var s1 = Directory1.FullName.Length;
|
||||
foreach (var file in Directory1.GetFiles("*.*", SearchOption.AllDirectories)) {
|
||||
var fullname = GetRootName (file, s1);
|
||||
var key = GetKey(fullname);
|
||||
items.Add(key, new Item () {
|
||||
Directory = Path.GetDirectoryName (fullname),
|
||||
Name = Path.GetFileName (file.Name),
|
||||
Info1 = file,
|
||||
});
|
||||
}
|
||||
// process 2nd directory
|
||||
var s2 = Directory2.FullName.Length;
|
||||
foreach (var file in Directory2.GetFiles ("*.*", SearchOption.AllDirectories)) {
|
||||
var fullname = GetRootName (file, s2);
|
||||
var key = GetKey(fullname);
|
||||
Item item;
|
||||
if (!items.TryGetValue (key, out item)) {
|
||||
item = new Item () {
|
||||
Directory = Path.GetDirectoryName (fullname),
|
||||
Name = Path.GetFileName (file.Name),
|
||||
};
|
||||
items.Add(key, item);
|
||||
}
|
||||
item.Info2 = file;
|
||||
}
|
||||
|
||||
// display
|
||||
Start();
|
||||
foreach (var kvp in items.OrderBy ((arg) => arg.Key)) {
|
||||
Process(kvp.Value);
|
||||
}
|
||||
End();
|
||||
}
|
||||
|
||||
public virtual void Start ()
|
||||
{
|
||||
}
|
||||
|
||||
public abstract void Process (Item item);
|
||||
|
||||
public virtual void End ()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
using System;
|
||||
using Tools;
|
||||
|
||||
namespace AppCompare {
|
||||
class MainClass {
|
||||
public static void Main (string[] args)
|
||||
{
|
||||
var dc = new AppComparer (args [0], args [1]);
|
||||
dc.Compare ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
# Application Comparer
|
||||
|
||||
Compare the file sizes between two versions of the same app bundle.
|
||||
|
||||
The tool outputs markdown so it's easier to read from a gist.
|
||||
|
||||
## Usage
|
||||
|
||||
```shell
|
||||
dotnet run <app1> <app2>
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```shell
|
||||
dotnet run MyOldApp.app MyNewApp.app > out
|
||||
gist out -t md -o
|
||||
```
|
|
@ -1,9 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<RootNamespace>app_compare</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
Загрузка…
Ссылка в новой задаче