”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > “警惕时间复杂度陷阱”

“警惕时间复杂度陷阱”

发布于2024-08-16
浏览:853

“Be wary of time complexity pitfalls\

警惕时间复杂度陷阱

写在这里

bilibili视频也显示了这个:[Bilibili视频][https://www.bilibili.com/video/BV16u4m1c7cU/?spm_id_from=333.999.0.0]我认为这是一个很好的视频,但它的语言是中文。

时间复杂度

  • 时间复杂度是什么意思?
  • 时间复杂度是算法运行所需时间的度量,作为其输入大小的函数。它是描述算法效率的一种方式,用于比较不同的算法并确定哪种算法最有效。

  • 如何计算时间复杂度?

  • 为了计算时间复杂度,我们需要考虑算法执行的操作数作为输入大小的函数。测量操作次数的最常见方法是计算执行特定操作的次数。

  • 计算时间复杂度时有哪些常见陷阱?

    1. 不考虑输入大小:如果我们只考虑算法执行的操作数量,我们可能会低估时间复杂度。例如,如果我们计算循环运行的次数,但不考虑输入的大小,那么时间复杂度可能会太高。
    1. 不考虑算法的效率:有些算法即使输入量很小也可能执行很多操作,这可能导致时间复杂度很高。例如,冒泡排序和选择排序等排序算法具有二次时间复杂度,即使它们可能只需要交换小数组中的两个元素。
    1. 不考虑算法的最坏情况:某些算法具有最好情况,其中执行的操作比最坏情况要少。例如,像二分搜索这样的搜索算法有一个最好的情况,即它们在对数时间内找到目标元素,但它们有一个最坏的情况,即它们需要检查数组中的所有元素。

让我们看一些时间复杂度的例子

这里有一个问题:
查找列表中最多 10 个整数。

import random
ls = [random.randint(1, 100) for _ in range(n)]

这里是测试函数:

import time
def benchmark(func, *args) -> float:
    start = time.perf_counter()
    func(*args)
    end = time.perf_counter()
    return end - start

解决方案1:使用堆

这是使用heapq模块的解决方案:

def find_max_n(ls, n):
    import heapq
    return heapq.nlargest(n, ls)

或者我们用python的方式写:

def find_largest_n(nums, n):
    if n  max_heap[0]:
            max_heap[0] = num
            _sift_down(max_heap, 0)

    return max_heap

def _sift_down(heap, index):
    left = 2 * index   1
    right = 2 * index   2
    largest = index

    if left  heap[largest]:
        largest = left

    if right  heap[largest]:
        largest = right

    if largest != index:
        heap[index], heap[largest] = heap[largest], heap[index]
        _sift_down(heap, largest)

解决方案2:使用排序

这里是使用排序功能的解决方案:

def find_max_n(ls, n):
    return sorted(ls, reverse=True)[:n]

几乎所有人都知道,堆的时间复杂度是 O(n log k),排序函数的时间复杂度是 O(n log n)。

看来第一个解决方案比第二个更好。但在Python中却并非如此。

看最终代码:

import time
def benchmark(func, *args) -> float:
    start = time.perf_counter()
    func(*args)
    end = time.perf_counter()
    return end - start

def find_max_n_heapq(ls, n):
    import heapq
    return heapq.nlargest(n, ls)

def find_max_n_python_heap(nums, n):
    if n  max_heap[0]:
            max_heap[0] = num
            _sift_down(max_heap, 0)

    return max_heap

def _sift_down(heap, index):
    left = 2 * index   1
    right = 2 * index   2
    largest = index

    if left  heap[largest]:
        largest = left

    if right  heap[largest]:
        largest = right

    if largest != index:
        heap[index], heap[largest] = heap[largest], heap[index]
        _sift_down(heap, largest)


def find_max_n_sorted(ls, n):
    return sorted(ls, reverse=True)[:n]

# test
import random
for n in range(10, 10000, 100):
    ls = [random.randint(1, 100) for _ in range(n)]
    print(f"n = {n}")
    print(f"Use    Heapq: {benchmark(find_max_n_heapq, ls, n)}")
    print(f"Python Heapq: {benchmark(find_max_n_python_heap, ls, n)}")
    print(f"Sorted      : {benchmark(find_max_n_sorted, ls, n)}")

我在Python3.11 VScode中运行,结果如下:

n 不大

使用堆:0.002430099993944168
Python堆:0.06343129999004304
排序:9.280000813305378e-05
n = 910
使用堆:9.220000356435776e-05
Python堆:0.07715500006452203
排序:9.360001422464848e-05
n = 920
使用堆:9.440002031624317e-05
Python堆:0.06573969998862594
排序:0.00012450001668184996
n = 930
使用堆:9.689992293715477e-05
Python堆:0.06760239996947348
已排序:9.66999214142561e-05
n = 940
使用堆:9.600003249943256e-05
Python堆:0.07372559991199523
排序:9.680003859102726e-05
n = 950
使用堆:9.770004544407129e-05
Python堆:0.07306570000946522
排序:0.00011979998089373112
n = 960
使用堆:9.980006143450737e-05
Python堆:0.0771204000338912
排序:0.00022829999215900898
n = 970
使用堆:0.0001601999392732978
Python堆:0.07493270002305508
排序:0.00010840001050382853
n = 980
使用堆:9.949994273483753e-05
Python 堆:0.07698320003692061
排序:0.00010300008580088615
n = 990
使用堆:9.979994501918554e-05
Python堆:0.0848745999392122
排序:0.00012620002962648869

如果n很大?

n = 10000
使用堆:0.003642000025138259
Python 堆:9.698883199947886
排序:0.00107999995816499
n = 11000
使用堆:0.0014836000045761466
Python 堆:10.537632800056599
排序:0.0012236000038683414
n = 12000
使用堆:0.001384599949233234
Python 堆:12.328411899972707
排序:0.0013226999435573816
n = 13000
使用堆:0.0020017001079395413
Python 堆:15.637207800056785
排序:0.0015075999544933438
n = 14000
使用堆:0.0017026999266818166
Python 堆:17.298848500009626
排序:0.0016967999981716275
n = 15000
使用堆:0.0017773000290617347
Python 堆:20.780625900020823
排序:0.0017105999868363142

我发现了什么以及如何改进它

当n很大时,Sorted会花费一点时间(有时甚至比使用heapq更好),但Python Heapq会花费很多时间。

  • 为什么Sorted花费一点时间,而Python Heapq花费很多时间?
  • 因为sorted()是Python中的内置函数,所以你可以找到关于它的Python官方文档。

内置函数比 heapq 更快,因为它是用 C 编写的,C 是一种编译语言。

  • 如何改进?
  • 您可以使用内置函数sorted()代替heapq.sort()来提高代码的性能。 Sorted() 函数是 Python 中的内置函数,它是用 C 实现的,因此比 heapq.sort()
  • 快得多

脑震荡

当我们处理大数据时,我们应该使用内置函数而不是 heapq.sort() 来提高代码的性能。在处理大数据时,我们必须警惕时间复杂度陷阱。有时时间复杂度的陷阱是不可避免的,但我们应该尽量避免它们。

关于我

大家好,我是梦沁园。我是一名学生。我喜欢学习新事物。
你可以看我的github:[MengQinYuan的Github][https://github.com/mengqinyuan]

版本声明 本文转载于:https://dev.to/mengqinyuan/be-wary-of-time-complexity-pitfalls-13jf?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 反射动态实现Go接口用于RPC方法探索
    反射动态实现Go接口用于RPC方法探索
    在GO 使用反射来实现定义RPC式方法的界面。例如,考虑一个接口,例如:键入myService接口{ 登录(用户名,密码字符串)(sessionId int,错误错误) helloworld(sessionid int)(hi String,错误错误) } 替代方案而不是依靠反射...
    编程 发布于2025-07-03
  • 为什么HTML无法打印页码及解决方案
    为什么HTML无法打印页码及解决方案
    无法在html页面上打印页码? @page规则在@Media内部和外部都无济于事。 HTML:Customization:@page { margin: 10%; @top-center { font-family: sans-serif; font-weight: bo...
    编程 发布于2025-07-03
  • Python中嵌套函数与闭包的区别是什么
    Python中嵌套函数与闭包的区别是什么
    嵌套函数与python 在python中的嵌套函数不被考虑闭合,因为它们不符合以下要求:不访问局部范围scliables to incling scliables在封装范围外执行范围的局部范围。 make_printer(msg): DEF打印机(): 打印(味精) ...
    编程 发布于2025-07-03
  • 如何将来自三个MySQL表的数据组合到新表中?
    如何将来自三个MySQL表的数据组合到新表中?
    mysql:从三个表和列的新表创建新表 答案:为了实现这一目标,您可以利用一个3-way Join。 选择p。*,d.content作为年龄 来自人为p的人 加入d.person_id = p.id上的d的详细信息 加入T.Id = d.detail_id的分类法 其中t.taxonomy =...
    编程 发布于2025-07-03
  • 为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    使用php dateTime修改月份:发现预期的行为在使用PHP的DateTime类时,添加或减去几个月可能并不总是会产生预期的结果。正如文档所警告的那样,“当心”这些操作的“不像看起来那样直观。 ; $ date->修改('1个月'); //前进1个月 echo $ date->...
    编程 发布于2025-07-03
  • 如何从PHP中的数组中提取随机元素?
    如何从PHP中的数组中提取随机元素?
    从阵列中的随机选择,可以轻松从数组中获取随机项目。考虑以下数组:; 从此数组中检索一个随机项目,利用array_rand( array_rand()函数从数组返回一个随机键。通过将$项目数组索引使用此键,我们可以从数组中访问一个随机元素。这种方法为选择随机项目提供了一种直接且可靠的方法。
    编程 发布于2025-07-03
  • Java是否允许多种返回类型:仔细研究通用方法?
    Java是否允许多种返回类型:仔细研究通用方法?
    在Java中的多个返回类型:一种误解类型:在Java编程中揭示,在Java编程中,Peculiar方法签名可能会出现,可能会出现,使开发人员陷入困境,使开发人员陷入困境。 getResult(string s); ,其中foo是自定义类。该方法声明似乎拥有两种返回类型:列表和E。但这确实是如此吗...
    编程 发布于2025-07-03
  • 如何在JavaScript对象中动态设置键?
    如何在JavaScript对象中动态设置键?
    在尝试为JavaScript对象创建动态键时,如何使用此Syntax jsObj['key' i] = 'example' 1;不工作。正确的方法采用方括号: jsobj ['key''i] ='example'1; 在JavaScript中,数组是一...
    编程 发布于2025-07-03
  • 在UTF8 MySQL表中正确将Latin1字符转换为UTF8的方法
    在UTF8 MySQL表中正确将Latin1字符转换为UTF8的方法
    在UTF8表中将latin1字符转换为utf8 ,您遇到了一个问题,其中含义的字符(例如,“jáuòiñe”)在utf8 table tabled tablesset中被extect(例如,“致电。为了解决此问题,您正在尝试使用“ mb_convert_encoding”和“ iconv”转换受...
    编程 发布于2025-07-03
  • Python环境变量的访问与管理方法
    Python环境变量的访问与管理方法
    Accessing Environment Variables in PythonTo access environment variables in Python, utilize the os.environ object, which represents a mapping of envir...
    编程 发布于2025-07-03
  • 您如何在Laravel Blade模板中定义变量?
    您如何在Laravel Blade模板中定义变量?
    在Laravel Blade模板中使用Elegance 在blade模板中如何分配变量对于存储以后使用的数据至关重要。在使用“ {{}}”分配变量的同时,它可能并不总是最优雅的解决方案。幸运的是,Blade通过@php Directive提供了更优雅的方法: $ old_section =“...
    编程 发布于2025-07-03
  • 解决Spring Security 4.1及以上版本CORS问题指南
    解决Spring Security 4.1及以上版本CORS问题指南
    弹簧安全性cors filter:故障排除常见问题 在将Spring Security集成到现有项目中时,您可能会遇到与CORS相关的错误,如果像“访问Control-allo-allow-Origin”之类的标头,则无法设置在响应中。为了解决此问题,您可以实现自定义过滤器,例如代码段中的MyFi...
    编程 发布于2025-07-03
  • Java中Lambda表达式为何需要“final”或“有效final”变量?
    Java中Lambda表达式为何需要“final”或“有效final”变量?
    Lambda Expressions Require "Final" or "Effectively Final" VariablesThe error message "Variable used in lambda expression shou...
    编程 发布于2025-07-03
  • 如何在无序集合中为元组实现通用哈希功能?
    如何在无序集合中为元组实现通用哈希功能?
    在未订购的集合中的元素要纠正此问题,一种方法是手动为特定元组类型定义哈希函数,例如: template template template 。 struct std :: hash { size_t operator()(std :: tuple const&tuple)const {...
    编程 发布于2025-07-03
  • 在Ubuntu/linux上安装mysql-python时,如何修复\“ mysql_config \”错误?
    在Ubuntu/linux上安装mysql-python时,如何修复\“ mysql_config \”错误?
    mysql-python安装错误:“ mysql_config找不到”“ 由于缺少MySQL开发库而出现此错误。解决此问题,建议在Ubuntu上使用该分发的存储库。使用以下命令安装Python-MysqldB: sudo apt-get安装python-mysqldb sudo pip in...
    编程 发布于2025-07-03

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3