- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
如果对 float 进行排序,C# 中的 Array.Sort 非常快,我需要一些额外的数据来处理这些 float ,所以我创建了一个简单的类并扩展了 IComparable 接口(interface)。现在 Array.Sort 突然慢了 3-4 倍,这是为什么?我该如何提高性能?
演示代码:
using System;
using System.Diagnostics;
using System.Linq;
namespace SortTest
{
class Program
{
static void Main(string[] args)
{
int arraySize = 10000;
int loops = 500;
double normalFloatTime = 0;
double floatWithIDTime = 0;
double structTime = 0;
double arraySortOverloadTime = 0;
bool floatWithIDCorrect = true;
bool structCorrect = true;
bool arraySortOverloadCorrect = true;
//just so we know the program is busy
Console.WriteLine("Sorting random arrays, this will take some time...");
Random random = new Random();
Stopwatch sw = new Stopwatch();
for (int i = 0; i < loops; i++)
{
float[] normalFloatArray = new float[arraySize];
SortTest[] floatWithIDArray = new SortTest[arraySize];
SortStruct[] structArray = new SortStruct[arraySize];
SortTest[] arraySortOverloadArray = new SortTest[arraySize];
//fill the arrays
for (int j = 0; j < arraySize; j++)
{
normalFloatArray[j] = NextFloat(random);
floatWithIDArray[j] = new SortTest(normalFloatArray[j], j);
structArray[j] = new SortStruct(normalFloatArray[j], j);
arraySortOverloadArray[j] = new SortTest(normalFloatArray[j], j);
}
//Reset stopwatch from any previous state
sw.Reset();
sw.Start();
Array.Sort(normalFloatArray);
sw.Stop();
normalFloatTime += sw.ElapsedTicks;
//Reset stopwatch from any previous state
sw.Reset();
sw.Start();
Array.Sort(floatWithIDArray);
sw.Stop();
floatWithIDTime += sw.ElapsedTicks;
//Reset stopwatch from any previous state
sw.Reset();
sw.Start();
Array.Sort(structArray);
sw.Stop();
structTime += sw.ElapsedTicks;
//Reset stopwatch from any previous state
sw.Reset();
sw.Start();
Array.Sort(arraySortOverloadArray.Select(k => k.ID).ToArray(), arraySortOverloadArray);
sw.Stop();
arraySortOverloadTime += sw.ElapsedTicks;
for (int k = 0; k < normalFloatArray.Length; k++)
{
if (normalFloatArray[k] != floatWithIDArray[k].SomeFloat)
{
floatWithIDCorrect = false;
}
if (normalFloatArray[k] != structArray[k].SomeFloat)
{
structCorrect = false;
}
if (normalFloatArray[k] != arraySortOverloadArray[k].SomeFloat)
{
arraySortOverloadCorrect = false;
}
}
}
//calculate averages
double normalFloatAverage = normalFloatTime / loops;
double floatWithIDAverage = floatWithIDTime / loops;
double structAverage = structTime / loops;
double arraySortOverloadAverage = arraySortOverloadTime / loops;
//print averages
Console.WriteLine("normalFloatAverage: {0} ticks.\nfloatWithIDAverage: {1} ticks.\nstructAverage: {2} ticks.\narraySortOverloadAverage: {3} ticks.", normalFloatAverage, floatWithIDAverage, structAverage, arraySortOverloadAverage);
Console.WriteLine("floatWithIDArray has " + (floatWithIDCorrect ? "" : "NOT ") + "been sorted correctly atleast once.");
Console.WriteLine("structArray has " + (structCorrect ? "" : "NOT ") + "been sorted correctly atleast once.");
Console.WriteLine("arraySortOverloadArray has " + (arraySortOverloadCorrect ? "" : "NOT ") + "been sorted correctly atleast once.");
Console.WriteLine("Press enter to exit.");
//pause so we can see the console
Console.ReadLine();
}
static float NextFloat(Random random)
{
double mantissa = (random.NextDouble() * 2.0) - 1.0;
double exponent = Math.Pow(2.0, random.Next(-126, 128));
return (float)(mantissa * exponent);
}
}
class SortTest : IComparable<SortTest>
{
public float SomeFloat;
public int ID;
public SortTest(float f, int id)
{
SomeFloat = f;
ID = id;
}
public int CompareTo(SortTest other)
{
float f = other.SomeFloat;
if (SomeFloat < f)
return -1;
else if (SomeFloat > f)
return 1;
else
return 0;
}
}
struct SortStruct : IComparable<SortStruct>
{
public float SomeFloat;
public int ID;
public SortStruct(float f, int id)
{
SomeFloat = f;
ID = id;
}
public int CompareTo(SortStruct other)
{
float f = other.SomeFloat;
if (SomeFloat < f)
return -1;
else if (SomeFloat > f)
return 1;
else
return 0;
}
}
}
演示输出:
Sorting random arrays, this will take some time...
normalFloatAverage: 3840,998 ticks.
floatWithIDAverage: 12850.672 ticks.
Press enter to exit.
编辑:我更新了代码以使用结构和委托(delegate)进行排序,如下所示,没有区别。
新的演示输出:
Sorting random arrays, this will take some time...
normalFloatAverage: 3629.092 ticks.
floatWithIDAverage: 12721.622 ticks.
structAverage: 12870.584 ticks.
Press enter to exit.
编辑 2:我已经根据下面的一些建议更新了我的代码,使其成为一个结构,要么对我的电脑没有影响,要么我做错了一些可怕的事情。我还添加了一些完整性检查。
新的演示输出(不要让“至少一次”骗了你,它用词不当):
Sorting random arrays, this will take some time...
normalFloatAverage: 3679.928 ticks.
floatWithIDAverage: 14084.794 ticks.
structAverage: 11725.364 ticks.
arraySortOverloadAverage: 2186.3 ticks.
floatWithIDArray has been sorted correctly atleast once.
structArray has been sorted correctly atleast once.
arraySortOverloadArray has NOT been sorted correctly atleast once.
Press enter to exit.
编辑 3:我再次更新了演示代码,修复了 Array.Sort 的重载方法。请注意,我在 Stopwatch 外部创建并填充了 test[] ,因为在我的例子中我已经有了该数组。 arraySortOverload 在 Debug模式下速度更快,在 Release模式下与结构方法差不多快。
新的演示输出(发布):
Sorting random arrays, this will take some time...
normalFloatAverage: 2384.578 ticks.
floatWithIDAverage: 6405.866 ticks.
structAverage: 4583.992 ticks.
arraySortOverloadAverage: 4551.104 ticks.
floatWithIDArray has been sorted correctly all the time.
structArray has been sorted correctly all the time.
arraySortOverloadArray has been sorted correctly all the time.
Press enter to exit.
最佳答案
有两种小方法可以加快速度:
对于 floatWithIDAverage
,还有一种加快速度的主要方法:使用 x86 而不是 x64。 (但这不会加速 normalFloatAverage
!)
进行任何更改之前的结果(对于 RELEASE 构建,而不是 DEBUG 构建):
x64:
normalFloatAverage: 2469.86 ticks.
floatWithIDAverage: 6172.564 ticks.
x86:
normalFloatAverage: 3071.544 ticks.
floatWithIDAverage: 6036.546 ticks.
将 SortTest 更改为结构后的结果:
此更改允许编译器进行大量优化。
x64:
normalFloatAverage: 2307.552 ticks.
floatWithIDAverage: 4214.414 ticks.
x86:
normalFloatAverage: 3054.814 ticks.
floatWithIDAverage: 4541.864 ticks.
更改 SortTest.CompareTo() 后的结果如下:
public int CompareTo(SortTest other)
{
float f = other.SomeFloat;
if (SomeFloat < f)
return -1;
else if (SomeFloat > f)
return 1;
else
return 0;
}
此更改消除了调用 float.CompareTo()
的开销。
x64:
normalFloatAverage: 2323.834 ticks.
floatWithIDAverage: 3721.254 ticks.
x86:
normalFloatAverage: 3087.314 ticks.
floatWithIDAverage: 3074.364 ticks.
最后,在这种特定情况下,floatWithIDAverage
实际上比 normalFloatAverage
更快。
x86 和 x64 的区别很有趣!
normalFloatAverage
,x64 比 x86 更快floatWithIDAverage
,x86 比 x64 更快结论
虽然对于 floatWithIDAverage
,我无法解释为什么 x86 版本比 x64 版本快得多,但我已经展示了一种显着加快速度的方法。
关于c# - 对类实例而不是 float 进行排序时 Array.Sort() 性能下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27961805/
我在玩一些代码挑战时发现自定义排序(排序接口(interface)的实现)比仅针对 slice 的原始结构要快得多。这是为什么?将 slice 转换为类型是否会产生一些魔力(例如转换为指向结构的指针
我正在使用 simple-import-sort eslint 插件进行 react 。我想我的 .eslintrc.js是对的,但我无法使这个特定的插件工作。我在文件的第一行收到以下错误: 未找到规
Closed. This question is not reproducible or was caused by typos。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-to
好的,所以我是 Go 的新手,我正在努力让自己熟悉按函数排序。我可能误解了什么,所以如果我错了请纠正我。 我正在尝试创建一个包含字段 key 和 value 的 Nodes 数组。我想创建一个自定义排
我想从惰性列表中取出 n 个最大的元素。 我听说在 Data.List.sort 中实现的合并排序是惰性的,它不会产生不必要的元素。就比较而言,这可能是正确的,但在内存使用方面肯定不是这样。下面的程序
这个问题已经有答案了: Javascript sort function. Sort by First then by Second (10 个回答) 已关闭 3 年前。 我正在尝试返回已排序产品的列
我有一个 vector 对,如下所示。第一对值未排序,第二对值已排序(从零开始)。我可能想通过实现 std::vector 和 std::pair 来存储数据。当我有第一对值(未排序)时,找到相应的第
直到现在(Swift 2.2)我一直愉快地使用来自 this answer 的代码- 它迅速,优雅,它像梦一样工作。 extension MutableCollectionType where Ind
我在我的 Go 应用程序中实现排序界面时遇到问题。这是相关代码: type Group struct { Teams []*Team } type Team struct { Point
我很好奇 Lua 的默认算法是什么 table.sort使用,只是因为它比我遇到的其他一些排序算法慢。我也很好奇 Lua 的 table.sort是在引擎中用 C 编写的,或者如果它在 Lua 中的库
例如,插入排序被描述为部分排序数组的有效算法。但如何精确定义“部分排序”呢? 最佳答案 这是一个只有少数元素不合适的数组。如果没有指定百分比或其他阈值,则部分排序和未排序之间没有严格的区别。 正式定义
我是 GPU 编程的新手。最近,我正在尝试根据一个教程实现gpu bvh构建算法:http://devblogs.nvidia.com/parallelforall/thinking-parallel
有人可以指导我 Gnumeric 排序函数的详细说明(链接)吗? Gnumeric 手册很简短并且没有示例。我无法通过搜索引擎找到任何合适的信息,甚至 Stackoverflow 上也只有六个不合适的
在 Python 中使用什么精确规则来对列表进行排序,其中元素是列表?这可以表示为“key”或“cmp”吗功能?问题来自于有两件事考虑:长度和它们位置的值。 sorted([ [ 0, 1, 2
下面的代码应该创建一个整数数组 (a) 并对它进行排序,但是 sort.Sort 似乎没有修改变量。 package main import ( "fmt" "sort" ) type
我有一个应用于结构的自定义排序函数。完整代码是 here on play.golang.org . type Stmt struct { Name string After []st
python3 sorted取消了对cmp的支持。 python3 帮助文档: ?
以下是来自普林斯顿的 coursera 算法类(class)的练习。 如果一个数组既是 3 次排序又是 5 次排序,那么它是否也是 6 次、7 次、8 次、9 次和 10 次排序?我知道任何序列如果先
当我看到上面的语句时,我正在阅读 shell-sorting。这意味着什么?它对我看待 shell 排序的方式有何不同? PS:我不是在寻找声明的证据。 最佳答案 好吧,你可能暗示下一个排序阶段不会“
今天在检查mysql服务器的时候提示Sort aborted: Out of sort memory, consider increasing server sort buffer size,安装字
我是一名优秀的程序员,十分优秀!