对动态大小的对象进行排序

2024-04-08

Problem

假设我有一个包含一些数据的大字节数组(最多 4GB)。这些字节对应于不同的对象,使得每个s字节(认为 s 最多 32)将构成单个对象。一个重要的事实是这个尺寸s对于所有对象都是相同的,不存储在对象本身中,并且在编译时不知道。

目前,这些对象只是逻辑实体,而不是编程语言中的对象。我对这些对象进行了比较,其中包括对大多数对象数据进行字典顺序比较,并使用一些不同的功能来使用剩余数据打破联系。现在我想对这些对象进行排序有效率的(这确实会成为应用程序的瓶颈)。

到目前为止的想法

我想到了几种可能的方法来实现这一目标,但每种方法似乎都会产生一些相当不幸的后果。您不必阅读所有这些内容。我尝试用粗体打印每种方法的核心问题。 If你将建议其中一种方法,then您的答案也应该回答相关问题。

1.C快速排序

当然,C 快速排序算法也可用于 C++ 应用程序。它的签名几乎完全符合我的要求。但事实上,使用该函数将禁止比较函数的内联,这意味着每次比较都会产生函数调用开销。我本来希望有一种方法可以避免这种情况。任何关于如何C的经验qsort_r与STL相比,在性能方面会非常受欢迎。

2. 使用指向数据的对象进行间接访问

编写一堆持有各自数据指针的对象是很容易的。然后就可以对它们进行排序。这里有两个方面需要考虑。一方面,仅移动指针而不是移动所有数据意味着更少的内存操作。另一方面,不移动对象可能会破坏内存局部性,从而破坏缓存性能。更深层次的快速排序递归实际上可以从几个缓存页面访问所有数据的机会几乎完全消失。相反,每个缓存的内存页在被替换之前只会产生很少的可用数据项。如果有人可以提供一些关于复制和内存局部性之间权衡的经验,我会非常高兴。

3. 自定义迭代器、引用和值对象

我编写了一个类,用作内存范围上的迭代器。取消引用此迭代器不会产生引用,而是会产生一个新构造的对象来保存指向数据和大小的指针s这是在迭代器构造时给出的。所以这些对象可以进行比较,我什至有一个实现std::swap对于这些。不幸的是,看来std::swap还不够std::sort。在该过程的某些部分,我的 gcc 实现使用插入排序(如__insertion_sort在文件中stl_alog.h) 将一个值移出序列,将多个项目移动一步,然后将第一个值移回序列中的适当位置:

          typename iterator_traits<_RandomAccessIterator>::value_type
            __val = _GLIBCXX_MOVE(*__i);
          _GLIBCXX_MOVE_BACKWARD3(__first, __i, __i + 1);
          *__first = _GLIBCXX_MOVE(__val);

您是否知道不需要值类型但可以单独使用交换操作的标准排序实现?

所以我不仅需要我的类作为参考,而且我还需要一个类来保存临时值。由于我的对象的大小是动态的,我必须在堆上分配它,这意味着内存分配在递归树的最叶子上。也许一种替代方案是具有静态大小的 vue 类型,该类型应该足够大以容纳我当前打算支持的大小的对象。但这意味着两国之间的关系将会出现更多的黑客行为。reference_typevalue_type的迭代器类。这意味着我必须更新我的应用程序的大小,以便有一天支持更大的对象。丑陋的。

如果您能想到一种干净的方法来让上述代码来操作我的数据,而不必动态分配内存,那将是一个很好的解决方案。我已经在使用 C++11 功能,因此使用移动语义或类似功能不会有问题。

4. 自定义排序

我什至考虑重新实现所有的快速排序。也许我可以利用这样一个事实,即我的比较主要是字典比较,即我可以按第一个字节对序列进行排序,并且仅当所有元素的第一个字节都相同时才切换到下一个字节。我还没有弄清楚这方面的细节,但是如果有人可以建议一个参考、一个实现,甚至一个规范名称来用作这种按字节词典排序的关键字,我会非常高兴。我仍然不相信只要我付出合理的努力,我就能超越 STL 模板实现的性能。

5.完全不同的算法

我知道有很多很多那里有各种各样的排序算法。其中一些可能更适合我的问题。基数排序我首先想到的是这个,但我还没有真正考虑清楚。如果您可以建议更适合我的问题的排序算法,请这样做。最好有实施,但即使没有。

Question

所以基本上我的问题是这样的:
“如何有效地对堆内存中动态大小的对象进行排序?”

这个问题的任何答案只要适合我的情况就是好的,无论是否与我自己的想法有关。对以粗体标记的各个问题的答案,或任何其他可能帮助我在替代方案之间做出决定的见解,也将很有用,特别是如果对单一方法没有明确的答案时。


最实用的解决方案是使用C风格qsort你提到的。

template <unsigned S>
struct my_obj {
    enum { SIZE = S; };
    const void *p_;
    my_obj (const void *p) : p_(p) {}
    //...accessors to get data from pointer
    static int c_style_compare (const void *a, const void *b) {
        my_obj aa(a);
        my_obj bb(b);
        return (aa < bb) ? -1 : (bb < aa);
    }
};

template <unsigned N, typename OBJ>
void my_sort (const char (&large_array)[N], const OBJ &) {
    qsort(large_array, N/OBJ::SIZE, OBJ::SIZE, OBJ::c_style_compare);
}

(或者,您可以致电qsort_r如果你愿意的话。)从STL开始sort内联比较调用,您可能无法获得最快的排序。如果您的系统所做的只是排序,那么添加代码以使自定义迭代器正常工作可能是值得的。但是,如果您的系统大部分时间都在做排序以外的事情,那么您获得的额外增益可能对整个系统来说只是噪音。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对动态大小的对象进行排序 的相关文章

随机推荐

  • 使用 sql 通过 csv 将产品导入到 woocommerce

    当sql表post meta不断增长时 通过插件wp all import导入产品会花费太多时间 目前有200 000种产品进口 有没有办法直接在sql中通过csv导入产品而不需要wordpress 我不需要导入任何图像 只需导入标题和描述
  • 应用程序图标创建叠加信息(数字)?

    如何在 Android 应用程序上克隆此行为 iOS 从技术上讲 这绝对是可能的 因为我在 Android 手机上有一个自己的应用程序 它是一个电子邮件应用程序 图标上有一个非常相似的指示器 显示未读邮件数量 是的 你可以像 ios 一样实
  • 用户输入-DOS批处理文件

    我得到一个bat文件 如下所示 ECHO Executing scripts PAUSE for X in SQL do SQLCMD S localhost d CTL I i X gt gt ResultScript txt pause
  • 以编程方式更改滑动时的 ViewPager 动画持续时间

    我正在使用以下代码更改幻灯片 viewPager setCurrentItem index true 但变化太快了 有没有办法手动设置动画速度 I ve wanted to do myself and have achieved a sol
  • 我可以在全局范围内只安装 Gulp 吗?

    我一直致力于新的网络开发项目 这些项目在实践中并不需要他们的node modules部署时的文件夹 如果我能够创建一个小的 它会更适合我gulpfile js对于每个项目 而不是包含在 6000 多个文件node modules每个项目的文
  • 在 Restful Web 服务中下载文件

    我的要求是 我应该通过restful服务向客户端发送一个10MB的zip文件 我在论坛中找到了发送StreamingOutput对象是更好的方法 但是我如何创建一个StreamingOutput以下代码中的对象 Path PDF file
  • 使用“Object.create”而不是“new”

    Javascript 1 9 3 ECMAScript 5 介绍Object create 其中道格拉斯 克罗克福德 Douglas Crockford 等人提倡 http javascript crockford com prototyp
  • 如何从一组 N 个对象中选择 n 个对象,最大化它们之间的成对距离之和

    您有一组 N 400 个对象 每个对象在 19 维空间中都有自己的坐标 您计算 欧几里德 距离矩阵 所有成对距离 现在您想要选择 n 50 个对象 使得所选对象之间所有成对距离的总和最大 我设计了一种通过线性编程来解决这个问题的方法 下面的
  • 如何使用完成处理程序将图像放入 SwiftUI 视图中

    我已经尝试过这个 但我不知道如何在 SwiftUI 视图中使用结果 func getProfilePicture completion escaping UIImage gt Void Alamofire request GIDSignIn
  • 关于如何构建 HTML Diff 工具的建议?

    In 这个帖子 https stackoverflow com questions 48669 are there any tools out there to compare the structure of 2 web pages我问是
  • SQL Server 进程队列竞争条件

    我有一个订单队列 多个订单处理器通过存储过程访问该队列 每个处理器都会传递一个唯一的 ID 该 ID 用于锁定接下来的 20 个订单以供自己使用 然后 存储过程将这些记录返回给订单处理器以进行操作 有些情况下多个处理器能够检索相同的 Ord
  • MYSQL限制特定列值的出现次数

    从数据库中提取一些优惠券 每张优惠券都有一个merchantid包含优惠券所属商家 ID 的列 我正在尝试构建一个提取 5 张优惠券的查询 但我只想要每张 1 张优惠券merchantid 我不想要多张相同的优惠券merchantid 你可
  • strtol 重用参数

    该代码似乎按预期工作 使用单个指针填充数字数组 include
  • 您可以指定嵌入 IPython 后运行的命令吗?

    打电话时IPython embed 是否可以给它一个命令或魔术函数来在嵌入发生后运行 我想运行这样的东西 import IPython IPython embed command pylab qt4 我当前的解决方法是将命令字符串复制到剪贴
  • 在 boost::spirit 语法中翻转规则内的子规则顺序会导致段错误

    警告 虽然我试图将代码缩短到最少 我仍然需要包含相当多的内容 以确保提供所需的信息 该代码编译文件并运行 导致语法错误 name simple name qi val qi 1 qualified name qi val qi 1 虽然这
  • 将前导零填充到公共宽度[重复]

    这个问题在这里已经有答案了 我正在处理具有小时格式的数据库 例如 HOUR ID 1 2 10 4 5 6 20 6 我想在 1 个字符的值中放置一个零 并将它们存储在名为 NHOUR 的新列中 例如 NHOUR HOUR ID 01 1
  • 如何以角度从一个组件打开模态到另一个组件?

    我创建模态模态组件并在 modal component html 文件中编码我的模态 我想在标头组件的 header component html 文件中使用此模式 我的 header component html 的相关部分如下 div
  • 可以从 http(javascript 客户端)直接向 Amazon SQS 发送请求吗?

    是否可以直接从 JavaScript 向 Amazon 的 SQS 发送消息请求 我正在尝试创建一个日志系统 并且希望绕过将请求发送到中间人服务器 另外 有人知道我可以利用这个解决方案的任何替代方案吗 SQS 事实上所有 aws 服务 都公
  • SQL 内连接。 ON 条件与 WHERE 子句

    我正忙于将使用旧样式语法的查询转换为新的联接语法 我的查询的实质如下 原始查询 SELECT i FROM InterestRunDailySum i InterestRunDetail ird InterestPayments p WHE
  • 对动态大小的对象进行排序

    Problem 假设我有一个包含一些数据的大字节数组 最多 4GB 这些字节对应于不同的对象 使得每个s字节 认为 s 最多 32 将构成单个对象 一个重要的事实是这个尺寸s对于所有对象都是相同的 不存储在对象本身中 并且在编译时不知道 目