-
Notifications
You must be signed in to change notification settings - Fork 0
Добавила решение задачи #1
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
base: main
Are you sure you want to change the base?
Changes from all commits
5a85559
2c5a4ac
836051d
2a7ef3d
468d0bf
b2ecc7d
271782f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>net7.0</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
|
|
||
| <IsPackable>false</IsPackable> | ||
| <IsTestProject>true</IsTestProject> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" /> | ||
| <PackageReference Include="NUnit" Version="3.13.3" /> | ||
| <PackageReference Include="NUnit3TestAdapter" Version="4.4.2" /> | ||
| <PackageReference Include="NUnit.Analyzers" Version="3.6.1" /> | ||
| <PackageReference Include="coverlet.collector" Version="3.2.0" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\Homework1\Homework1.csproj" /> | ||
| </ItemGroup> | ||
| </Project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| namespace Homework1.Tests; | ||
|
|
||
| public class Tests | ||
| { | ||
| Matrix matrix1; | ||
| Matrix matrix2; | ||
|
|
||
| [SetUp] | ||
| public void Setup() | ||
| { | ||
| matrix1 = new(new int[2, 3] { { 1, 2, 3 }, { 3, 5, 6 } }, 2, 3); | ||
| matrix2 = new(new int[3, 2] { { 1, 2 }, { 3, 5 }, { 3, 0 } }, 3, 2); | ||
| } | ||
|
|
||
| [Test] | ||
| public void ExceptionsTest() | ||
| { | ||
| Assert.Throws<ArgumentNullException>(() => new Matrix(null)); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тут nullability-анализ ругается, если хотите null, напишите |
||
| Assert.Throws<ArgumentNullException>(() => Matrix.MultiThreadedMultiplyingMatrixes(null, matrix1)); | ||
| Assert.Throws<ArgumentNullException>(() => Matrix.MultiThreadedMultiplyingMatrixes(matrix1, null)); | ||
| Assert.Throws<ArgumentException>(() => Matrix.MultiThreadedMultiplyingMatrixes(matrix1, matrix1)); | ||
| Assert.Throws<ArgumentNullException>(() => Matrix.SequentialMultiplyingMatrixes(null, matrix1)); | ||
| Assert.Throws<ArgumentNullException>(() => Matrix.SequentialMultiplyingMatrixes(matrix1, null)); | ||
| Assert.Throws<ArgumentException>(() => Matrix.SequentialMultiplyingMatrixes(matrix1, matrix1)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void EqualCalculationTest() | ||
| { | ||
| Matrix matrix3 = Matrix.SequentialMultiplyingMatrixes(matrix1, matrix2); | ||
| Matrix matrix4 = Matrix.MultiThreadedMultiplyingMatrixes(matrix1, matrix2); | ||
|
|
||
| Assert.Multiple(() => | ||
| { | ||
| Assert.That(matrix4.Height, Is.EqualTo(matrix3.Height)); | ||
| Assert.That(matrix4.Width, Is.EqualTo(matrix3.Width)); | ||
| }); | ||
|
|
||
| for (int i = 0; i < matrix4.Height; i++) | ||
| { | ||
| for (int j = 0; j < matrix3.Width; j++) | ||
| { | ||
| Assert.That(matrix4.MatrixOfNumbers[i, j], Is.EqualTo(matrix3.MatrixOfNumbers[i, j])); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| [Test] | ||
| public void RightCalculationTest() | ||
| { | ||
| var matrix3 = Matrix.SequentialMultiplyingMatrixes(matrix1, matrix2); | ||
| Matrix matrix4 = new(new int[2, 2] { { 16, 12 }, { 36, 31 } }, 2, 2); | ||
|
|
||
| Assert.Multiple(() => | ||
| { | ||
| Assert.That(matrix4.Height, Is.EqualTo(matrix3.Height)); | ||
| Assert.That(matrix4.Width, Is.EqualTo(matrix3.Width)); | ||
| }); | ||
|
|
||
| for (int i = 0; i < matrix4.Height; i++) | ||
| { | ||
| for (int j = 0; j < matrix3.Width; j++) | ||
| { | ||
| Assert.That(matrix4.MatrixOfNumbers[i, j], Is.EqualTo(matrix3.MatrixOfNumbers[i, j])); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| global using NUnit.Framework; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| namespace Homework1; | ||
|
|
||
| using System.Diagnostics; | ||
|
|
||
| public static class ComparisonMatrixCountingSpeeds | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Надо комментарии ко всем типам и всем public-членам |
||
| { | ||
| public static (double, double)[] Experiments(int sizeOfData, int amountOfTestsInSample) //size of data, mathematical expectation, dispersion | ||
| { | ||
| List<long> timeByThreads = new(); | ||
| List<long> timeSequential = new(); | ||
| for (int testNumber = 0; testNumber < amountOfTestsInSample; testNumber++) | ||
| { | ||
| int[,] numbersInMatrix1 = CreateSquareArrayWithRandomValues(sizeOfData); | ||
| int[,] numbersInMatrix2 = CreateSquareArrayWithRandomValues(sizeOfData); | ||
| Matrix matrix1 = new(numbersInMatrix1, sizeOfData, sizeOfData); | ||
| Matrix matrix2 = new(numbersInMatrix2, sizeOfData, sizeOfData); | ||
| timeByThreads.Add(TimeOfMultiThreadedMultiplying(matrix1, matrix2)); | ||
| timeSequential.Add(TimeOfSequentialMultiplying(matrix1, matrix2)); | ||
| } | ||
| double? mathematicalExpectationByThreads = timeByThreads.Average(); | ||
| double? mathematicalExpectationSequential = timeSequential.Average(); | ||
| double dispersionByThreads = DispersionCalculator(timeByThreads, mathematicalExpectationByThreads.Value); | ||
| double dispersionSequential = DispersionCalculator(timeSequential, mathematicalExpectationSequential.Value); | ||
| return new (double, double)[] { (mathematicalExpectationByThreads.Value, dispersionByThreads), (mathematicalExpectationSequential.Value, dispersionSequential) }; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Вместо массива кортежей, где всегда должно быть два элемента, сделали бы специальный struct. Явные именованные поля лучше соглашений |
||
| } | ||
|
|
||
| private static double DispersionCalculator(List<long> time, double mathematicalExpectation) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Методы должны называться глаголами в повелительной форме |
||
| { | ||
| var sumOfSquareDifference = Enumerable.Range(0, time.Count).Sum(i => (time[i] - mathematicalExpectation) * (time[i] - mathematicalExpectation)); | ||
| return sumOfSquareDifference / time.Count; | ||
| } | ||
|
|
||
| private static int[,] CreateSquareArrayWithRandomValues(int size) | ||
| { | ||
| var random = new Random(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Random в принципе должен быть на систему один (во-первых потому, что больше одного не нужно, во-вторых, потому что он инициализируется временем, так что если два объекта Random создать одновременно, они просто одинаковые значения будут выдавать, в-третьих, сборщику мусора их ещё удалять). Так что сделайте его статическим полем. |
||
| var array = new int[size, size]; | ||
| for (int i = 0; i < size; i++) | ||
| { | ||
| for (int j = 0; j < size; j++) | ||
| { | ||
| array[i, j] = random.Next(); | ||
| } | ||
| } | ||
| return array; | ||
| } | ||
|
|
||
| private static long TimeOfMultiThreadedMultiplying(Matrix matrix1, Matrix matrix2) | ||
| { | ||
| var stopwatch = new Stopwatch(); | ||
| stopwatch.Start(); | ||
| Matrix.MultiThreadedMultiplyingMatrixes(matrix1, matrix2); | ||
| stopwatch.Stop(); | ||
| return stopwatch.ElapsedMilliseconds; | ||
| } | ||
|
|
||
| private static long TimeOfSequentialMultiplying(Matrix matrix1, Matrix matrix2) | ||
| { | ||
| var stopwatch = new Stopwatch(); | ||
| stopwatch.Start(); | ||
| Matrix.SequentialMultiplyingMatrixes(matrix1, matrix2); | ||
| stopwatch.Stop(); | ||
| return stopwatch.ElapsedMilliseconds; | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <OutputType>Exe</OutputType> | ||
| <TargetFramework>net7.0</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
| </PropertyGroup> | ||
|
|
||
| </Project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| | ||
| Microsoft Visual Studio Solution File, Format Version 12.00 | ||
| # Visual Studio Version 16 | ||
| VisualStudioVersion = 25.0.1706.3 | ||
| MinimumVisualStudioVersion = 10.0.40219.1 | ||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Homework1", "Homework1.csproj", "{14F8B15D-5607-477A-A472-19A069798644}" | ||
| EndProject | ||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Homework1.Tests", "..\Homework1.Tests\Homework1.Tests.csproj", "{79329A91-4C97-4EBF-A9CA-034DF6F6322E}" | ||
| EndProject | ||
| Global | ||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
| Debug|Any CPU = Debug|Any CPU | ||
| Release|Any CPU = Release|Any CPU | ||
| EndGlobalSection | ||
| GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
| {14F8B15D-5607-477A-A472-19A069798644}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| {14F8B15D-5607-477A-A472-19A069798644}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| {14F8B15D-5607-477A-A472-19A069798644}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
| {14F8B15D-5607-477A-A472-19A069798644}.Release|Any CPU.Build.0 = Release|Any CPU | ||
| {79329A91-4C97-4EBF-A9CA-034DF6F6322E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| {79329A91-4C97-4EBF-A9CA-034DF6F6322E}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| {79329A91-4C97-4EBF-A9CA-034DF6F6322E}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
| {79329A91-4C97-4EBF-A9CA-034DF6F6322E}.Release|Any CPU.Build.0 = Release|Any CPU | ||
| EndGlobalSection | ||
| GlobalSection(SolutionProperties) = preSolution | ||
| HideSolutionNode = FALSE | ||
| EndGlobalSection | ||
| GlobalSection(ExtensibilityGlobals) = postSolution | ||
| SolutionGuid = {00E31478-F7C2-44B2-A7A6-52E93083F34F} | ||
| EndGlobalSection | ||
| EndGlobal |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,180 @@ | ||||||||||||
| namespace Homework1; | ||||||||||||
|
|
||||||||||||
| /// <summary> | ||||||||||||
| /// The matrix class implements methods: | ||||||||||||
| /// matrix representation as a row, matrix multiplication by threads and sequential. | ||||||||||||
| /// </summary> | ||||||||||||
| public class Matrix | ||||||||||||
| { | ||||||||||||
| public int[,] MatrixOfNumbers { get; private set; } | ||||||||||||
| public int Height { get; private set; } = 0; | ||||||||||||
| public int Width { get; private set; } = 0; | ||||||||||||
|
|
||||||||||||
| /// <summary> | ||||||||||||
| /// Creates new instance of Matrix class by file content. | ||||||||||||
| /// </summary> | ||||||||||||
| public Matrix(string filePath) | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. лучше передавать в конструктор сразу ширину, высоту и данные. Так положено по правилам инкапсуляции. Вдруг пользователь захочет вводить из консоли? |
||||||||||||
| { | ||||||||||||
| if (filePath == null) | ||||||||||||
| { | ||||||||||||
| throw new ArgumentNullException(nameof(filePath)); | ||||||||||||
| } | ||||||||||||
| string[] matrixInLines = File.ReadAllLines(filePath); | ||||||||||||
| Height = matrixInLines.Length; | ||||||||||||
| if (Height < 1) | ||||||||||||
| { | ||||||||||||
| throw new ArgumentException("There is no numbers in file"); | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
| } | ||||||||||||
| string[] parsedFirstLine = matrixInLines[0].Split(" ", StringSplitOptions.RemoveEmptyEntries); | ||||||||||||
| Width = parsedFirstLine.Length; | ||||||||||||
| if (Width < 1) | ||||||||||||
| { | ||||||||||||
| throw new ArgumentException("There is no numbers in file"); | ||||||||||||
| } | ||||||||||||
| MatrixOfNumbers = new int[Height, Width]; | ||||||||||||
| for (int i = 0; i < Height; i++) | ||||||||||||
| { | ||||||||||||
| string line = matrixInLines[i]; | ||||||||||||
| string[] stringOfNumbers = line.Split(" ", StringSplitOptions.RemoveEmptyEntries); | ||||||||||||
| if (stringOfNumbers.Length != Width) | ||||||||||||
| { | ||||||||||||
| throw new ArgumentException("Amount of numbers in line isn't equal"); | ||||||||||||
| } | ||||||||||||
| if (i == 0) | ||||||||||||
| { | ||||||||||||
| Width = stringOfNumbers.Length; | ||||||||||||
| } | ||||||||||||
| for (int j = 0; j < Width; j++) | ||||||||||||
| { | ||||||||||||
| if (int.TryParse(stringOfNumbers[j], out int currentValue)) | ||||||||||||
| { | ||||||||||||
| MatrixOfNumbers[i, j] = currentValue; | ||||||||||||
| } | ||||||||||||
| else | ||||||||||||
| { | ||||||||||||
| throw new ArgumentException("Not inly numbers in file"); | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| /// <summary> | ||||||||||||
| /// Creates new instance of Matrix class. | ||||||||||||
| /// </summary> | ||||||||||||
| /// <param name="matrix"> matrix in array</param> | ||||||||||||
| /// <param name="height">matrix height</param> | ||||||||||||
| /// <param name="width">matrix width</param> | ||||||||||||
| public Matrix(int[,] matrix, int height, int width) | ||||||||||||
| { | ||||||||||||
| MatrixOfNumbers = matrix; | ||||||||||||
| Height = height; | ||||||||||||
| Width = width; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| /// <summary> | ||||||||||||
| /// return matrix in string | ||||||||||||
| /// </summary> | ||||||||||||
| public string PrintedMatrix() | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
| { | ||||||||||||
| string matrixInString = ""; | ||||||||||||
| for (int i = 0; i < Height; i++) | ||||||||||||
| { | ||||||||||||
| for (int j = 0; j < Width; j++) | ||||||||||||
| { | ||||||||||||
| matrixInString += Convert.ToString(MatrixOfNumbers[i, j]) + ' '; | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Никогда не конкатенируйте строки в цикле, это же постоянное копирование строк и аллокации. Используйте StringBuilder |
||||||||||||
| } | ||||||||||||
| matrixInString += '\n'; | ||||||||||||
| } | ||||||||||||
| return matrixInString; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| /// <summary> | ||||||||||||
| /// Multiplies matrixes sequential. | ||||||||||||
| /// </summary> | ||||||||||||
| public static Matrix SequentialMultiplyingMatrixes(Matrix matrix1, Matrix matrix2) | ||||||||||||
| { | ||||||||||||
| if (matrix1 == null) | ||||||||||||
| { | ||||||||||||
| throw new ArgumentNullException(nameof(matrix1)); | ||||||||||||
| } | ||||||||||||
|
Comment on lines
+96
to
+99
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
|
|
||||||||||||
| if (matrix2 == null) | ||||||||||||
| { | ||||||||||||
| throw new ArgumentNullException(nameof(matrix2)); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| if (matrix1.Width != matrix2.Height) | ||||||||||||
| { | ||||||||||||
| throw new ArgumentException("Matrix sizes are inconsistent"); | ||||||||||||
| } | ||||||||||||
| var matrix3Numbers = new int[matrix1.Height, matrix2.Width]; | ||||||||||||
| for (int i = 0; i < matrix1.Height; i++) | ||||||||||||
| { | ||||||||||||
| for (int j = 0; j < matrix2.Width; j++) | ||||||||||||
| { | ||||||||||||
| matrix3Numbers[i, j] = 0; | ||||||||||||
| for (int k = 0; k < matrix1.Width; k++) | ||||||||||||
| { | ||||||||||||
| matrix3Numbers[i, j] += matrix1.MatrixOfNumbers[i, k] * matrix2.MatrixOfNumbers[k, j]; | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| return new Matrix(matrix3Numbers, matrix1.Height, matrix2.Width); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| /// <summary> | ||||||||||||
| /// Multiplies matrixes by threads. | ||||||||||||
| /// </summary> | ||||||||||||
| public static Matrix MultiThreadedMultiplyingMatrixes(Matrix matrix1, Matrix matrix2) | ||||||||||||
| { | ||||||||||||
| if (matrix1 == null) | ||||||||||||
| { | ||||||||||||
| throw new ArgumentNullException(nameof(matrix1)); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| if (matrix2 == null) | ||||||||||||
| { | ||||||||||||
| throw new ArgumentNullException(nameof(matrix2)); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| if (matrix1.Width != matrix2.Height) | ||||||||||||
| { | ||||||||||||
| throw new ArgumentException("Matrix sizes are inconsistent"); | ||||||||||||
| } | ||||||||||||
| var matrix3Numbers = new int[matrix1.Height, matrix2.Width]; | ||||||||||||
|
|
||||||||||||
| int amountOfThreads = Environment.ProcessorCount; | ||||||||||||
| var matrixMyltiplyingThreads = new Thread[amountOfThreads]; | ||||||||||||
|
Comment on lines
+147
to
+148
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Так может получиться больше потоков, чем нужно. В матрице может быть меньше Environment.ProcessorCount строк |
||||||||||||
|
|
||||||||||||
| for (int i = 0; i < matrixMyltiplyingThreads.Length; i++) | ||||||||||||
| { | ||||||||||||
| int threadFirstLine = i; | ||||||||||||
| uint amountOfElementsInMatrix = (uint)matrix1.Height * (uint)matrix2.Width; | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. uint -- тоже слишком низкоуровнево. Не стоит заморачиваться такими вещами, пиши There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Всё так, хотя и некритично. Лишние аннотации типов в целом не мешают |
||||||||||||
| matrixMyltiplyingThreads[i] = new Thread(() => | ||||||||||||
| { | ||||||||||||
| int currentLine = threadFirstLine; | ||||||||||||
| while (currentLine < matrix1.Height) | ||||||||||||
| { | ||||||||||||
| for (int currentColumn = 0; currentColumn < matrix2.Width; ++currentColumn) | ||||||||||||
| { | ||||||||||||
| matrix3Numbers[currentLine, currentColumn] = Enumerable.Range(0, matrix1.Width).Sum(multiplyingIndex => matrix1.MatrixOfNumbers[currentLine, multiplyingIndex] * matrix2.MatrixOfNumbers[multiplyingIndex, currentColumn]); | ||||||||||||
| } | ||||||||||||
| currentLine += amountOfThreads; | ||||||||||||
| } | ||||||||||||
| }); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| foreach (var thread in matrixMyltiplyingThreads) | ||||||||||||
| { | ||||||||||||
| thread.Start(); | ||||||||||||
| } | ||||||||||||
| foreach (var thread in matrixMyltiplyingThreads) | ||||||||||||
| { | ||||||||||||
| thread.Join(); | ||||||||||||
| } | ||||||||||||
| return new Matrix(matrix3Numbers, matrix1.Height, matrix2.Width); | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
В .NET по традиции всегда явно пишут модификаторы видимости, даже если умолчания устраивают