Add performance benchmarks for dataframe arithmetic operations (#6827)

* Add performance tests

* Add extra tests

* Fix

* Fix typo

* Fix Divide_Int16 and Divide_Int32_Int16 benchmarks

* Fix

* Change csproj file

* Update BenchmarkDotNetVersion to 0.13.5

* Fix

* Change to 0.13.1 because that is what is latest version in our nuget feeds.

---------

Co-authored-by: Jake Radzikowski <JakeRad@Microsoft.com>
This commit is contained in:
Aleksei Smirnov 2023-09-26 20:23:39 +03:00 коммит произвёл GitHub
Родитель a052146947
Коммит 15e6a556ce
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 255 добавлений и 8 удалений

Просмотреть файл

@ -168,6 +168,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.Tokenizers.Tes
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Microsoft.ML.FSharp.Tests", "test\Microsoft.ML.FSharp.Tests\Microsoft.ML.FSharp.Tests.fsproj", "{041CB5CD-5832-413E-A894-D9DBED210B16}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Data.Analysis.PerformanceTests", "test\Microsoft.Data.Analysis.PerformanceTests\Microsoft.Data.Analysis.PerformanceTests.csproj", "{FB8A8823-CC6C-4C2F-8539-05FBFB7C91CD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -788,6 +790,14 @@ Global
{041CB5CD-5832-413E-A894-D9DBED210B16}.Release|Any CPU.Build.0 = Release|Any CPU
{041CB5CD-5832-413E-A894-D9DBED210B16}.Release|x64.ActiveCfg = Release|Any CPU
{041CB5CD-5832-413E-A894-D9DBED210B16}.Release|x64.Build.0 = Release|Any CPU
{FB8A8823-CC6C-4C2F-8539-05FBFB7C91CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FB8A8823-CC6C-4C2F-8539-05FBFB7C91CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FB8A8823-CC6C-4C2F-8539-05FBFB7C91CD}.Debug|x64.ActiveCfg = Debug|Any CPU
{FB8A8823-CC6C-4C2F-8539-05FBFB7C91CD}.Debug|x64.Build.0 = Debug|Any CPU
{FB8A8823-CC6C-4C2F-8539-05FBFB7C91CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FB8A8823-CC6C-4C2F-8539-05FBFB7C91CD}.Release|Any CPU.Build.0 = Release|Any CPU
{FB8A8823-CC6C-4C2F-8539-05FBFB7C91CD}.Release|x64.ActiveCfg = Release|Any CPU
{FB8A8823-CC6C-4C2F-8539-05FBFB7C91CD}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -870,6 +880,7 @@ Global
{BBC3A950-BD68-45AC-9DBD-A8F4D8847745} = {09EADF06-BE25-4228-AB53-95AE3E15B530}
{C3D82402-F207-4F19-8C57-5AF0FBAF9682} = {AED9C836-31E3-4F3F-8ABC-929555D3F3C4}
{041CB5CD-5832-413E-A894-D9DBED210B16} = {AED9C836-31E3-4F3F-8ABC-929555D3F3C4}
{FB8A8823-CC6C-4C2F-8539-05FBFB7C91CD} = {AED9C836-31E3-4F3F-8ABC-929555D3F3C4}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {41165AF1-35BB-4832-A189-73060F82B01D}

Просмотреть файл

@ -74,7 +74,7 @@
<SystemCompositionVersion>1.2.0</SystemCompositionVersion>
<!-- Test-only Dependencies -->
<ApprovalTestsVersion>5.4.7</ApprovalTestsVersion>
<BenchmarkDotNetVersion>0.12.0</BenchmarkDotNetVersion>
<BenchmarkDotNetVersion>0.13.1</BenchmarkDotNetVersion>
<DotNetRuntime60Version>6.0.9</DotNetRuntime60Version>
<DotNetRuntime80Version>8.0.0-preview.3.23174.8</DotNetRuntime80Version>
<FluentAssertionVersion>5.10.2</FluentAssertionVersion>

Просмотреть файл

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<ImplicitUsings>disable</ImplicitUsings>
<TargetFrameworks>net6.0</TargetFrameworks>
<GenerateProgramFile>false</GenerateProgramFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="$(BenchmarkDotNetVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.Data.Analysis\Microsoft.Data.Analysis.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,202 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
namespace Microsoft.Data.Analysis.PerformanceTests
{
public class PerformanceTests
{
private const int ItemsCount = 1000000;
private Int32DataFrameColumn _int32Column1;
private Int32DataFrameColumn _int32Column2;
private Int16DataFrameColumn _int16Column1;
private Int16DataFrameColumn _int16Column2;
private DoubleDataFrameColumn _doubleColumn1;
private DoubleDataFrameColumn _doubleColumn2;
private SingleDataFrameColumn _floatColumn1;
private SingleDataFrameColumn _floatColumn2;
[GlobalSetup]
public void SetUp()
{
var values = Enumerable.Range(1, ItemsCount).ToArray();
_int32Column1 = new Int32DataFrameColumn("Column1", values);
_int32Column2 = new Int32DataFrameColumn("Column2", values);
var shortValues = values.Select(v => (short)(v % short.MaxValue + 1)).ToArray();
_int16Column1 = new Int16DataFrameColumn("Column1", shortValues);
_int16Column2 = new Int16DataFrameColumn("Column2", shortValues);
_doubleColumn1 = new DoubleDataFrameColumn("Column1", values.Select(v => (double)v));
_doubleColumn2 = new DoubleDataFrameColumn("Column2", values.Select(v => (double)v));
_floatColumn1 = new SingleDataFrameColumn("Column1", values.Select(v => (float)v));
_floatColumn2 = new SingleDataFrameColumn("Column2", values.Select(v => (float)v));
}
#region Addition
[Benchmark]
public void Add_Int32()
{
var column = _int32Column1 + _int32Column2;
}
[Benchmark]
public void Add_Int16()
{
var column = _int16Column1 + _int16Column2;
}
[Benchmark]
public void Add_Double()
{
var column = _doubleColumn1 + _doubleColumn2;
}
[Benchmark]
public void Add_Float()
{
var column = _floatColumn1 + _floatColumn2;
}
[Benchmark]
public void Add_Int32_Int16()
{
var column = _int32Column1 + _int16Column2;
}
[Benchmark]
public void Add_Double_Float()
{
var column = _doubleColumn1 + _floatColumn2;
}
#endregion
#region Subtract
[Benchmark]
public void Subtract_Int32()
{
var column = _int32Column1 - _int32Column2;
}
[Benchmark]
public void Subtract_Int16()
{
var column = _int16Column1 - _int16Column2;
}
[Benchmark]
public void Subtract_Double()
{
var column = _doubleColumn1 - _doubleColumn2;
}
[Benchmark]
public void Subtract_Float()
{
var column = _floatColumn1 - _floatColumn2;
}
[Benchmark]
public void Subtract_Int32_Int16()
{
var column = _int32Column1 - _int16Column2;
}
[Benchmark]
public void Subtract_Double_Float()
{
var column = _doubleColumn1 - _floatColumn2;
}
#endregion
#region Multiply
[Benchmark]
public void Multiply_Int32()
{
var column = _int32Column1 * _int32Column2;
}
[Benchmark]
public void Multiply_Int16()
{
var column = _int16Column1 * _int16Column2;
}
[Benchmark]
public void Multiply_Double()
{
var column = _doubleColumn1 * _doubleColumn2;
}
[Benchmark]
public void Multiply_Float()
{
var column = _floatColumn1 * _floatColumn2;
}
[Benchmark]
public void Multiply_Int32_Int16()
{
var column = _int32Column1 * _int16Column2;
}
[Benchmark]
public void Multiply_Double_Float()
{
var column = _doubleColumn1 * _floatColumn2;
}
#endregion
#region Divide
[Benchmark]
public void Divide_Int32()
{
var column = _int32Column1 / _int32Column2;
}
[Benchmark]
public void Divide_Int16()
{
var column = _int16Column1 / _int16Column2;
}
[Benchmark]
public void Divide_Double()
{
var column = _doubleColumn1 / _doubleColumn2;
}
[Benchmark]
public void Divide_Float()
{
var column = _floatColumn1 / _floatColumn2;
}
[Benchmark]
public void Divide_Int32_Int16()
{
var column = _int32Column1 / _int16Column2;
}
[Benchmark]
public void Divide_Double_Float()
{
var column = _doubleColumn1 / _floatColumn2;
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,17 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using BenchmarkDotNet.Running;
namespace Microsoft.Data.Analysis.PerformanceTests
{
class Program
{
public static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<PerformanceTests>();
}
}
}

Просмотреть файл

@ -52,7 +52,7 @@ namespace Microsoft.ML.PerformanceTests.Tests
[MemberData(nameof(GetBenchmarks))]
public void BenchmarksProjectIsNotBroken(Type type)
{
var summary = BenchmarkRunner.Run(type, new TestConfig().With(new OutputLogger(output)));
var summary = BenchmarkRunner.Run(type, new TestConfig().AddLogger(new OutputLogger(output)));
Assert.False(summary.HasCriticalValidationErrors, "The \"Summary\" should have NOT \"HasCriticalValidationErrors\"");

Просмотреть файл

@ -16,8 +16,7 @@ namespace Microsoft.ML.CpuMath.PerformanceTests
.Run(args, CreateCustomConfig());
private static IConfig CreateCustomConfig()
=> DefaultConfig.Instance
.With(Job.Default
.With(InProcessEmitToolchain.Instance));
=> DefaultConfig.Instance.AddJob(Job.Default
.WithToolchain(InProcessEmitToolchain.Instance));
}
}

Просмотреть файл

@ -20,11 +20,11 @@ namespace Microsoft.ML.PerformanceTests
{
Add(DefaultConfig.Instance); // this config contains all of the basic settings (exporters, columns etc)
Add(GetJobDefinition() // job defines how many times given benchmark should be executed
AddJob(GetJobDefinition()// job defines how many times given benchmark should be executed
.WithCustomBuildConfiguration(GetBuildConfigurationName())
.With(CreateToolchain())); // toolchain is responsible for generating, building and running dedicated executable per benchmark
.WithToolchain(CreateToolchain())); // toolchain is responsible for generating, building and running dedicated executable per benchmark
Add(new ExtraMetricColumn()); // an extra column that can display additional metric reported by the benchmarks
AddColumn(new ExtraMetricColumn()); // an extra column that can display additional metric reported by the benchmarks
}
protected virtual Job GetJobDefinition()