我的编程空间,编程开发者的网络收藏夹
学习永远不晚

对切片进行排序:利用排序方法实现切片排序

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

对切片进行排序:利用排序方法实现切片排序

目前编程网上已经有很多关于Golang的文章了,自己在初次阅读这些文章中,也见识到了很多学习思路;那么本文《对切片进行排序:利用排序方法实现切片排序》,也希望能帮助到大家,如果阅读完后真的对你学习Golang有帮助,欢迎动动手指,评论留言并分享~

问题内容

我正在尝试一些代码挑战,发现自定义排序(排序接口的实现)比仅针对切片的原始结构要快得多。这是为什么?切片到类型的转换是否有一些魔力(例如转换为结构体指针的切片)?

我编写了一些代码来测试我的hipotesis

package sortingexample

import (
    "sort"
    "testing"
)

// example of struct we going to sort.

type point struct {
    x, y int
}

// --- struct / raw data
var testcases = []point{
    {10, 3},
    {10, 4},
    {10, 35},
    {10, 5},
    {10, 51},
    {10, 25},
    {10, 59},
    {10, 15},
    {10, 22},
    {10, 91},
}

// example one - sorting slice directly
// somehow - slowest way to sort it.
func sortslice(points []point) {
    sort.slice(points, func(i, j int) bool {
        return points[i].y < points[j].y
    })
}

func benchmarkslice(b *testing.b) {
    tmp := make([]point, len(testcases))
    for i := 0; i < b.n; i++ {
        copy(tmp, testcases)
        sortslice(tmp)
    }
}

// example two - sorting slice directly
// much faster performance
type points []point

// sort interface implementation
func (p points) less(i, j int) bool { return p[i].y < p[j].y }
func (p points) len() int           { return len(p) }
func (p points) swap(i, j int)      { p[i], p[j] = p[j], p[i] }

func sortstruct(points []point) {
    sort.sort(points(points))
}

func benchmarkstruct(b *testing.b) {
    tmp := make([]point, len(testcases))
    for i := 0; i < b.n; i++ {
        copy(tmp, testcases)
        sortstruct(tmp)
    }
}

// --- pointers
var testcasespoints = []*point{
    &point{10, 3},
    &point{10, 4},
    &point{10, 35},
    &point{10, 5},
    &point{10, 51},
    &point{10, 25},
    &point{10, 59},
    &point{10, 15},
    &point{10, 22},
    &point{10, 91},
}

// example three - sorting slice of pointers

func sortslicepointers(points []*point) {
    sort.slice(points, func(i, j int) bool {
        return points[i].y < points[j].y
    })
}

func benchmarkslicepointers(b *testing.b) {
    tmp := make([]*point, len(testcasespoints))
    for i := 0; i < b.n; i++ {
        copy(tmp, testcasespoints)
        sortslicepointers(tmp)
    }
}

// example four - sorting struct (with slice of pointers beneath it)
type pointspointer []*point

func (pp pointspointer) less(i, j int) bool { return pp[i].y < pp[j].y }
func (pp pointspointer) len() int           { return len(pp) }
func (pp pointspointer) swap(i, j int)      { pp[i], pp[j] = pp[j], pp[i] }

func sortstructofslicepointers(points []*point) {
    sort.sort(pointspointer(points))
}

func benchmarkstructofslicepointers(b *testing.b) {
    tmp := make([]*point, len(testcasespoints))

    for i := 0; i < b.n; i++ {
        copy(tmp, testcasespoints)
        sortstructofslicepointers(tmp)
    }
}

这是结果...

> go test -bench=.
goos: darwin
goarch: amd64
BenchmarkSlice-4                     3000000           542 ns/op
BenchmarkStruct-4                    5000000           318 ns/op
BenchmarkSlicePointers-4             5000000           280 ns/op
BenchmarkStructOfSlicePointers-4     5000000           321 ns/op

很明显,对指针切片进行排序会更快,但为什么自定义排序实现更快呢?我可以阅读有关它的任何资源吗?


解决方案


通用 sort.Slice()sort.SliceStable() 函数适用于任何切片。您必须将切片值作为 interface{} 值传递,并且实现必须使用反射(reflect 包)来访问其元素和长度,并执行元素交换。

相反,当您自己实现 sort.Interface 类型时,在您的实现中您可以访问切片的静态类型,并且您可以提供 sort.interface 的实现而无需反射,这将使其更快。

因此,如果性能至关重要/重要,请始终自行提供 sort.interface 实现。如果切片很小或者性能不重要,您可以使用更方便的 sort.slice() 函数。

通过分配添加运行输出看起来接口/结构方法也更好。

❯ go version
go version go1.17.1 darwin/amd64
❯ go test -bench=. -benchmem
goos: darwin
goarch: amd64
pkg: github.com/timescale/promscale/pkg/api/parser/json/test
cpu: Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
BenchmarkSlice-12                        3533616               319.6 ns/op            88 B/op          3 allocs/op
BenchmarkStruct-12                       9157018               126.0 ns/op            24 B/op          1 allocs/op
BenchmarkSlicePointers-12                6643446               167.1 ns/op            56 B/op          2 allocs/op
BenchmarkStructOfSlicePointers-12        9004021               124.1 ns/op            24 B/op          1 allocs/op
PASS
ok      github.com/timescale/promscale/pkg/api/parser/json/test 5.425s

本篇关于《对切片进行排序:利用排序方法实现切片排序》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注编程网公众号!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

对切片进行排序:利用排序方法实现切片排序

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

对切片进行排序:利用排序方法实现切片排序

目前编程网上已经有很多关于Golang的文章了,自己在初次阅读这些文章中,也见识到了很多学习思路;那么本文《对切片进行排序:利用排序方法实现切片排序》,也希望能帮助到大家,如果阅读完后真的对你学习Golang有帮助,欢迎动动手指,评论留言并
对切片进行排序:利用排序方法实现切片排序
2024-04-04

按给定切片对切片字符串进行排序/排序

哈喽!大家好,很高兴又见面了,我是编程网的一名作者,今天由我给大家带来一篇《按给定切片对切片字符串进行排序/排序》,本文主要会讲到等等知识点,希望大家一起学习进步,也欢迎大家关注、点赞、收藏、转发! 下面就一起来看看吧!问题内容如何按照另一
按给定切片对切片字符串进行排序/排序
2024-04-04

对多维切片进行排序

Golang小白一枚,正在不断学习积累知识,现将学习到的知识记录一下,也是将我的所得分享给大家!而今天这篇文章《对多维切片进行排序》带大家来了解一下##content_title##,希望对大家的知识积累有所帮助,从而弥补自己的不足,助力实
对多维切片进行排序
2024-04-04

如何使用golang中的sort.Slice函数对切片进行排序

对切片进行排序是Golang中常用的一个功能,可以使用sort.Slice函数快速实现。这个函数允许通过传入一个自定义的比较函数来对切片进行排序。sort.Slice函数的定义如下:func Slice(slice interface{},
如何使用golang中的sort.Slice函数对切片进行排序
2023-11-18

详解Go语言如何使用标准库sort对切片进行排序

Sort 标准库提供了对基本数据类型的切片和自定义类型的切片进行排序的函数。今天主要分享的内容是使用 Go 标准库 sort 对切片进行排序,感兴趣的可以了解一下
2022-12-21

vue怎么实现拖动图片进行排序Vue.Draggable

这篇文章主要介绍了vue怎么实现拖动图片进行排序Vue.Draggable的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇vue怎么实现拖动图片进行排序Vue.Draggable文章都会有所收获,下面我们一起来看
2023-06-30

怎么在Python中利用排序算法实现插入排序

怎么在Python中利用排序算法实现插入排序,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、插入排序插入排序与我们平时打扑克牌非常相似,将新摸到的牌插入到已有的牌中合适的位置
2023-06-15

掌握Go语言文档中的sort.Slice函数实现切片排序

掌握Go语言文档中的sort.Slice函数实现切片排序,需要具体代码示例在Go语言中,切片是一种非常常见的数据结构,用于存储一系列相同类型的元素。在实际应用中,我们经常需要对切片进行排序,以满足不同的需求。Go语言中提供了sort包,其中
掌握Go语言文档中的sort.Slice函数实现切片排序
2023-11-03

PHP中对数组进行排序的方法

这篇文章主要介绍PHP中对数组进行排序的方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!php有什么用php是一个嵌套的缩写名称,是英文超级文本预处理语言,它的语法混合了C、Java、Perl以及php自创新的语法
2023-06-14

java中实现对类的对象进行排序

我们需要对类按照类中的某一个属性(或者多个属性)来对类的对象进行排序,有两种方法可以实现,一种方法是类实现Comparable接口,然后调用Collections.sort(List)方法进行排序,另一种方法是类不实现Comparable接口,而在排序时使用C
java中实现对类的对象进行排序
2022-03-08

Python实现针对中文排序的方法

本文实例讲述了Python实现针对中文排序的方法。分享给大家供大家参考,具体如下: Python比较字符串大小时,根据的是ord函数得到的编码值。基于它的排序函数sort可以很容易为数字和英文字母排序,因为它们在编码表中就是顺序排列的。>>
2022-06-04

如何在Windows 10和11上按面部对照片进行排序

Windows的操作随着每个版本而变得越来越好,具有诱人的功能来改善用户体验。用户希望在Windows 10和11上探索的一项功能是能够按面部对照片进行排序。此功能允许您通过面部识别对朋友和家人的照片进行分组。听起来很有趣,对吧?继续阅读如
2023-08-09

drupal按分类进行文章排序的实现方法

本文实例讲述了drupal按分类进行文章排序的实现方法。分享给大家供大家参考。具体实现方法如下: Drupal的文章组织形式,决定了其文章排序是一件比较麻烦的事。由于Drupal中没有“栏目”这样的概念,而采用了&l
2022-06-12

利用Java实现一个希尔排序的方法

利用Java实现一个希尔排序的方法?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、希尔排序(Shell Sort)希尔排序(Shell Sort)是一种插入排序算法,因D
2023-05-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录