Swift相当于Python切片赋值

Swift相当于Python切片赋值,第1张

概述在 Python中,可以有一个列表(类似于swift中的数组): >>> li=[0,1,2,3,4,5] 并在列表的任何/所有列表上执行切片分配: >>> li[2:]=[99] # note then end index is not needed if you mean 'to the end'>>> li[0, 1, 99] Swift有一个类似的切片赋值(这是在swi 在 Python中,可以有一个列表(类似于swift中的数组):

>>> li=[0,1,2,3,4,5]

并在列表的任何/所有列表上执行切片分配:

>>> li[2:]=[99]         # note then end index is not needed if you mean 'to the end'>>> li[0,99]

Swift有一个类似的切片赋值(这是在swift交互式shell中):

1> var arr=[0,5]arr: [Int] = 6 values {  [0] = 0  [1] = 1  [2] = 2  [3] = 3  [4] = 4  [5] = 5}  2> arr[2...arr.endindex-1]=[99]  3> arr$R0: [Int] = 3 values {  [0] = 0  [1] = 1  [2] = 99}

到现在为止还挺好.但是,有几个问题.

首先,swift不适用于空列表或索引位于endindex之后.如果切片索引在结束索引之后,则Python附加:

>>> li=[]             # empty>>> li[2:]=[6,7,8]>>> li[6,8]>>> li=[0,2]>>> li[999:]=[999]>>> li[0,999]

swift中的等价物是一个错误:

4> var arr=[Int]()arr: [Int] = 0 values  5> arr[2...arr.endindex-1]=[99]Fatal error: Can't form Range with end < start

这很容易测试和编码.

第二个问题是杀手:它的速度非常慢.考虑这个Python代码来执行浮点列表的精确求和:

def msum(iterable):    "Full precision summation using multiple floats for intermediate values"    # Rounded x+y stored in hi with the round-off stored in lo.  Together    # hi+lo are exactly equal to x+y.  The inner loop applIEs hi/lo summation    # to each partial so that the List of partial sums remains exact.    # Depends on IEEE-754 arithmetic guarantees.  See proof of correctness at:    # www-2.cs.cmu.edu/afs/cs/project/quake/public/papers/robust-arithmetic.ps    partials = []               # sorted,non-overlapPing partial sums    for x in iterable:        i = 0        for y in partials:            if abs(x) < abs(y):                x,y = y,x            hi = x + y            lo = y - (hi - x)            if lo:                partials[i] = lo                i += 1            x = hi        partials[i:] = [x]    return sum(partials,0.0)

它的工作原理是保持hi / lo部分求和,使msum([.1] * 10)精确地产生1.0而不是0.9999999999999999. ms的等效msum是Python中math library的一部分.

我试图在swift中复制:

func msum(it:[Double])->Double {    // Full precision summation using multiple floats for intermediate values     var partials=[Double]()    for var x in it {        var i=0        for var y in partials{            if abs(x) < abs(y){                (x,y)=(y,x)            }            let hi=x+y            let lo=y-(hi-x)            if abs(lo)>0.0 {                partials[i]=lo                i+=1            }            x=hi        }        // slow part trying to replicate Python's slice assignment partials[i:]=[x]        if partials.endindex>i {            partials[i...partials.endindex-1]=[x]        }        else {            partials.append(x)        }        }     return partials.reduce(0.0,combine: +)}

测试功能和速度:

import Foundationvar arr=[Double]()for _ in 1...1000000 {    arr+=[10,1e100,10,-1e100]    }print(arr.reduce(0,combine: +))    // will be 0.0var startTime: CFabsoluteTime!startTime = CFabsoluteTimeGetCurrent()print(msum(arr),arr.count*5)          // should be arr.count * 5print(CFabsoluteTimeGetCurrent() - startTime)

在我的机器上,需要7秒才能完成. Python native msum需要2.2秒(大约快4倍),库fsum函数需要0.09秒(几乎快90倍)

我试图用arr.removeRange(i ..< arr.endindex)替换partials [i ... partials.endindex-1] = [x]然后追加.快一点但不多. 题:
>这是惯用的swift:partials [i … partials.endindex-1] = [x]
>有更快/更好的方式吗?

解决方法 首先(正如评论中所说),有一个巨大的
Swift中非优化和优化代码之间的区别
(“-Onone”vs“-O”编译器选项,或DeBUG与Release配置),因此对于性能测试,请确保“Release”配置
被选中. (如果您,“发布”也是默认配置
用仪器描述代码).

使用半开范围有一些优点:

var arr = [0,5]arr[2 ..< arr.endindex] = [99]print(arr) // [0,99]

事实上,这是一个范围在内部存储的方式,它允许你
在数组末尾插入一个切片(但不超过Python中的切片):

var arr = [Int]()arr[0 ..< arr.endindex] = [99]print(arr) // [99]

所以

if partials.endindex > i {    partials[i...partials.endindex-1]=[x]}else {    partials.append(x)}

相当于

partials[i ..< partials.endindex] = [x] // Or: partials.replaceRange(i ..< partials.endindex,with: [x])

但是,这不是性能提升.看起来
在Swift中替换切片很慢.截断数组和
附加新元素

partials.replaceRange(i ..< partials.endindex,with: [])partials.append(x)

我的测试代码的时间从大约1.25秒减少到0.75秒电脑.

总结

以上是内存溢出为你收集整理的Swift相当于Python切片赋值全部内容,希望文章能够帮你解决Swift相当于Python切片赋值所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1009708.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存