-
Notifications
You must be signed in to change notification settings - Fork 0
Test #5
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?
Test #5
Changes from all commits
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 @@ | ||
| WFWFWEFWEFWVWwGVWvfegrebke eab fdaeio dferb rtnd dbaeb |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| dfveerbergb serubn er8h ss bevbs wb |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| namespace MD5Test; | ||
|
|
||
| public class Tests | ||
| { | ||
| [SetUp] | ||
| public void Setup() | ||
| { | ||
| } | ||
|
|
||
| [Test] | ||
| public async Task ShouldReultRemainTheSameForComputeCheckSumForFile() | ||
| { | ||
| var firstCompute = await Test.MD5.ComputeCheckSumForFile("..//..//..//text.txt"); | ||
| var secondCompute = await Test.MD5.ComputeCheckSumForFile("..//..//..//text.txt"); | ||
| Assert.That(firstCompute, Is.EquivalentTo(secondCompute)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void ShouldDirectoryNotFoundException() | ||
| { | ||
| Assert.ThrowsAsync<DirectoryNotFoundException>(() => Test.MD5.SequentiallyComputeCheckSumForDirectory("..//..//..//Ahaha")); | ||
| } | ||
|
|
||
| [Test] | ||
| public void ShouldFileNotFoundException() | ||
| { | ||
| Assert.ThrowsAsync<FileNotFoundException>(() => Test.MD5.ComputeCheckSumForFile("Ahaha.txt")); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>net6.0</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
|
|
||
| <IsPackable>false</IsPackable> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" /> | ||
| <PackageReference Include="NUnit" Version="3.13.3" /> | ||
| <PackageReference Include="NUnit3TestAdapter" Version="4.2.1" /> | ||
| <PackageReference Include="NUnit.Analyzers" Version="3.3.0" /> | ||
| <PackageReference Include="coverlet.collector" Version="3.1.2" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\Test\MD5.csproj" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |
| 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 @@ | ||
| wevwevw34g vw834vw 8g3wv hvewrvewrvv ervuuw wev wbvwv sw se ef bef |
| 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 17 | ||
| VisualStudioVersion = 17.2.32505.173 | ||
| MinimumVisualStudioVersion = 10.0.40219.1 | ||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MD5", "Test\MD5.csproj", "{9CC20C6D-177D-42E0-BB20-9BD0A99E44A1}" | ||
| EndProject | ||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MD5Test", "MD5Test\MD5Test.csproj", "{4BAAADE4-FE65-4B66-BE72-FE99B382017A}" | ||
| EndProject | ||
| Global | ||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
| Debug|Any CPU = Debug|Any CPU | ||
| Release|Any CPU = Release|Any CPU | ||
| EndGlobalSection | ||
| GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
| {9CC20C6D-177D-42E0-BB20-9BD0A99E44A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| {9CC20C6D-177D-42E0-BB20-9BD0A99E44A1}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| {9CC20C6D-177D-42E0-BB20-9BD0A99E44A1}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
| {9CC20C6D-177D-42E0-BB20-9BD0A99E44A1}.Release|Any CPU.Build.0 = Release|Any CPU | ||
| {4BAAADE4-FE65-4B66-BE72-FE99B382017A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| {4BAAADE4-FE65-4B66-BE72-FE99B382017A}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| {4BAAADE4-FE65-4B66-BE72-FE99B382017A}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
| {4BAAADE4-FE65-4B66-BE72-FE99B382017A}.Release|Any CPU.Build.0 = Release|Any CPU | ||
| EndGlobalSection | ||
| GlobalSection(SolutionProperties) = preSolution | ||
| HideSolutionNode = FALSE | ||
| EndGlobalSection | ||
| GlobalSection(ExtensibilityGlobals) = postSolution | ||
| SolutionGuid = {C9040189-AFF7-479F-B79D-90D73122038F} | ||
| EndGlobalSection | ||
| EndGlobal |
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,112 @@ | ||||||||||||||||
| namespace Test; | ||||||||||||||||
|
|
||||||||||||||||
| /// <summary> | ||||||||||||||||
| /// Class representing the calculation of the check sum | ||||||||||||||||
| /// </summary> | ||||||||||||||||
| public class MD5 | ||||||||||||||||
|
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. Все методы static, следовательно и сам класс мог бы быть static |
||||||||||||||||
| { | ||||||||||||||||
| public static async Task<byte[]> ComputeCheckSumForFile(string path) | ||||||||||||||||
|
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. А тут комментария не хватает. И я бы его и методы ниже сделал private — не пользователь должен решать, файл у нас или папка. Я как пользователь хочу просто передать путь и получить хеш, думать не хочу. |
||||||||||||||||
| { | ||||||||||||||||
| var md5 = System.Security.Cryptography.MD5.Create(); | ||||||||||||||||
| if (!File.Exists(path)) | ||||||||||||||||
| { | ||||||||||||||||
| throw new FileNotFoundException(); | ||||||||||||||||
| } | ||||||||||||||||
| using var fileStream = new FileStream(path, FileMode.Open); | ||||||||||||||||
| var bytes = await md5.ComputeHashAsync(fileStream); | ||||||||||||||||
| return bytes; | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| /// <summary> | ||||||||||||||||
| /// Function for sequential calculation of the check sum of the directory | ||||||||||||||||
| /// </summary> | ||||||||||||||||
| /// <param name="pathToDirectory">Path to directory</param> | ||||||||||||||||
| /// <returns></returns> | ||||||||||||||||
|
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. Пустые тэги не нужны |
||||||||||||||||
| /// <exception cref="DirectoryNotFoundException"></exception> | ||||||||||||||||
| public static async Task<byte[]> SequentiallyComputeCheckSumForDirectory(string pathToDirectory) | ||||||||||||||||
| { | ||||||||||||||||
| // Если директории не существует | ||||||||||||||||
|
|
||||||||||||||||
| if (!Directory.Exists(pathToDirectory)) | ||||||||||||||||
| { | ||||||||||||||||
| throw new DirectoryNotFoundException(); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| // Берем имена файлов | ||||||||||||||||
| var files = Directory.GetFiles(pathToDirectory); | ||||||||||||||||
|
|
||||||||||||||||
| // Имена директорий | ||||||||||||||||
| var directories = Directory.GetDirectories(pathToDirectory); | ||||||||||||||||
| var list = new List<(byte[], string)>(); | ||||||||||||||||
|
|
||||||||||||||||
| foreach(var directory in directories) | ||||||||||||||||
|
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
|
||||||||||||||||
| { | ||||||||||||||||
| list.Add((await SequentiallyComputeCheckSumForDirectory(directory), directory)); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| foreach (var file in files) | ||||||||||||||||
| { | ||||||||||||||||
| list.Add((await ComputeCheckSumForFile(file), file)); | ||||||||||||||||
| } | ||||||||||||||||
| var directoryName = System.Text.Encoding.UTF8.GetBytes(Path.GetDirectoryName(pathToDirectory)!); | ||||||||||||||||
|
|
||||||||||||||||
| // Сортируем для одинакового порядка полученных файлов | ||||||||||||||||
| list.Sort(); | ||||||||||||||||
|
|
||||||||||||||||
| foreach (var (lol, bytes) in list) | ||||||||||||||||
|
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. lol — League of Legends? :) Потому что в списке идут сначала байты, затем имя |
||||||||||||||||
| { | ||||||||||||||||
| var result = new byte[bytes.Length + lol.Length]; | ||||||||||||||||
| directoryName.CopyTo(result, 0); | ||||||||||||||||
| lol.CopyTo(result, bytes.Length); | ||||||||||||||||
| directoryName = result; | ||||||||||||||||
| } | ||||||||||||||||
|
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. И я вообще не понял, что тут происходит. Мы на каждой итерации цикла выделяем новый массив, вместо того, чтобы посчитать длину результата и выделить за один раз (избежав квадратичной трудоёмкости по памяти), не пользуемся Array.Concat, почему копирование с bytes.Length, хотя directoryName по длине не равно bytes.Length (и bytes вообще в процессе не участвует, так что зачем его длина, непонятно). И directoryName — это вовсе не directoryName уже после первой итерации. |
||||||||||||||||
| var md5 = System.Security.Cryptography.MD5.Create(); | ||||||||||||||||
| return md5.ComputeHash(directoryName); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| /// <summary> | ||||||||||||||||
| /// Function for parallel calculation of the check sum of the directory | ||||||||||||||||
| /// </summary> | ||||||||||||||||
| /// <param name="pathToDirectory">Path to directory</param> | ||||||||||||||||
| /// <returns></returns> | ||||||||||||||||
| /// <exception cref="DirectoryNotFoundException"></exception> | ||||||||||||||||
| public static byte[] ParallelComputeCheckSumForDirectory(string pathToDirectory) | ||||||||||||||||
| { | ||||||||||||||||
| // Если директории не существует | ||||||||||||||||
| if (!Directory.Exists(pathToDirectory)) | ||||||||||||||||
| { | ||||||||||||||||
| throw new DirectoryNotFoundException(); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| // Берем имена файлов | ||||||||||||||||
| var files = Directory.GetFiles(pathToDirectory); | ||||||||||||||||
|
|
||||||||||||||||
| // Имена директорий | ||||||||||||||||
| var directories = Directory.GetDirectories(pathToDirectory); | ||||||||||||||||
|
|
||||||||||||||||
| var list = new List<(byte[], string)>(); | ||||||||||||||||
|
|
||||||||||||||||
| // Изначально хотел сделать как в домашке с матрицами, а именно дать каждому изпотоков какое то количество файлов на обработку | ||||||||||||||||
| // После просто Task.Run(() => {...}) и объединять Task.Result | ||||||||||||||||
| // Но так вроде выглядит проще | ||||||||||||||||
| Parallel.ForEach(directories, directory => list.Add((ParallelComputeCheckSumForDirectory(directory), directory))); | ||||||||||||||||
| Parallel.ForEach(files, file => list.Add((ParallelComputeCheckSumForDirectory(file), file))); | ||||||||||||||||
|
Comment on lines
+92
to
+93
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. Вы не верите в гонки? :) 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. И ComputeCheckSumForFile тут. Как тестировали, оно же падает сразу? :) |
||||||||||||||||
|
|
||||||||||||||||
| // Сортируем для одинакового порядка полученных файлов | ||||||||||||||||
| list.Sort(); | ||||||||||||||||
|
|
||||||||||||||||
| // Первым идет имя директории | ||||||||||||||||
| var directoryName = System.Text.Encoding.UTF8.GetBytes(Path.GetDirectoryName(pathToDirectory)!); | ||||||||||||||||
|
|
||||||||||||||||
|
|
||||||||||||||||
| foreach (var (lol, bytes) in list) | ||||||||||||||||
|
Comment on lines
+99
to
+102
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
|
||||||||||||||||
| { | ||||||||||||||||
| var result = new byte[bytes.Length + lol.Length]; | ||||||||||||||||
| directoryName.CopyTo(result, 0); | ||||||||||||||||
| lol.CopyTo(result, bytes.Length); | ||||||||||||||||
| directoryName = result; | ||||||||||||||||
| } | ||||||||||||||||
| var md5 = System.Security.Cryptography.MD5.Create(); | ||||||||||||||||
| return md5.ComputeHash(directoryName); | ||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <OutputType>Exe</OutputType> | ||
| <TargetFramework>net6.0</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
| </PropertyGroup> | ||
|
|
||
| </Project> |
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,52 @@ | ||||||||||||||||
| using System.Diagnostics; | ||||||||||||||||
|
|
||||||||||||||||
| if (args.Length < 1) | ||||||||||||||||
| { | ||||||||||||||||
| Console.WriteLine("Количество аргументв должно быть не меньше 1"); | ||||||||||||||||
| return; | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
|
|
||||||||||||||||
| static (IEnumerable<long>, IEnumerable<long>) Calculate(string path) | ||||||||||||||||
|
Comment on lines
+7
to
+10
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
|
||||||||||||||||
| { | ||||||||||||||||
| var stopWatch = new Stopwatch(); | ||||||||||||||||
| var numberOfIterations = 100; | ||||||||||||||||
| var standardCalculations = new long[numberOfIterations]; | ||||||||||||||||
| var parallelCalculations = new long[numberOfIterations]; | ||||||||||||||||
| for (int i = 0; i < numberOfIterations; i++) | ||||||||||||||||
| { | ||||||||||||||||
| stopWatch.Reset(); | ||||||||||||||||
| stopWatch.Start(); | ||||||||||||||||
| var second = Test.MD5.SequentiallyComputeCheckSumForDirectory(path); | ||||||||||||||||
| stopWatch.Stop(); | ||||||||||||||||
| standardCalculations[i] = stopWatch.ElapsedMilliseconds; | ||||||||||||||||
|
|
||||||||||||||||
| stopWatch.Reset(); | ||||||||||||||||
| stopWatch.Start(); | ||||||||||||||||
| var first = Test.MD5.ParallelComputeCheckSumForDirectory(path); | ||||||||||||||||
| stopWatch.Stop(); | ||||||||||||||||
| parallelCalculations[i] = stopWatch.ElapsedMilliseconds; | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| return (standardCalculations, parallelCalculations); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| foreach (var path in args) | ||||||||||||||||
| { | ||||||||||||||||
| var (standardCalculations, parallelCalculations) = Calculate(path); | ||||||||||||||||
| var averageForStandardCalculations = Enumerable.Average(standardCalculations); | ||||||||||||||||
| var averageForParallelCalculations = Enumerable.Average(parallelCalculations); | ||||||||||||||||
| var varianceForStandardCalculations = Enumerable.Average(standardCalculations.Select(x => x * x)) - averageForStandardCalculations * averageForStandardCalculations; | ||||||||||||||||
| var varianceForParallelCalculations = Enumerable.Average(parallelCalculations.Select(x => x * x)) - averageForParallelCalculations * averageForParallelCalculations; | ||||||||||||||||
| //stream.WriteLine(); | ||||||||||||||||
| //stream.Write($"{size} {Math.Round(averageForStandardCalculations, 3)} {Math.Round(Math.Sqrt(varianceForStandardCalculations), 3)} {Math.Round(averageForParallelCalculations, 3)} {Math.Round(Math.Sqrt(varianceForParallelCalculations), 3)}"); | ||||||||||||||||
|
Comment on lines
+41
to
+42
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. :( |
||||||||||||||||
| Console.WriteLine($"Average operation time of standart : {Math.Round(averageForStandardCalculations, 3)}"); | ||||||||||||||||
| Console.WriteLine($"Standard deviation operation time of standart: {Math.Round(Math.Sqrt(varianceForStandardCalculations), 3)}"); | ||||||||||||||||
| Console.WriteLine(); | ||||||||||||||||
| Console.WriteLine($"Average operation time of parallel : {Math.Round(averageForParallelCalculations, 3)}"); | ||||||||||||||||
| Console.WriteLine($"Standard deviation operation time of parallel : {Math.Round(Math.Sqrt(varianceForParallelCalculations), 3)}"); | ||||||||||||||||
| Console.WriteLine(); | ||||||||||||||||
| Console.WriteLine(); | ||||||||||||||||
| Console.WriteLine(); | ||||||||||||||||
|
|
||||||||||||||||
| } | ||||||||||||||||

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.