如何定义新的 primitive type ?

julia> x = 1; y = 2; @btime x + y
  21.103 ns (0 allocations: 0 bytes)
3

julia> x = UInt128(1); y = UInt128(2); @btime x + y
  27.948 ns (1 allocation: 32 bytes)
0x00000000000000000000000000000003

julia> x = BigInt(1); y = BigInt(2); @btime x + y
  164.949 ns (3 allocations: 48 bytes)
3

BigInt 与 primitive type 相比,运行很慢,怎么定义一个 UInt256,加快下面代码的运行速度 ?

module Poly1305

using ..Common: LeBytes, little

const Poly1305KeyLen = 32
const prefix = BigInt(1) << 128
const p = BigInt(1) << 130 - 5

function Poly1305Cal(r::BigInt, a::BigInt, msg::Vector{UInt8}, isOver::Bool)
    len = length(msg)
    nblock = fld(len, 16)
    msgBlock = unsafe_wrap(Array{UInt128}, Ptr{UInt128}(pointer(msg)), nblock)

    a = foldl((x, y) -> (x + y + prefix) * r % p, msgBlock; init=a)

    if (local left = len % 16; left != 0)
        block = zeros(UInt8, 16)
        block[1:left] = unsafe_wrap(Array{UInt8}, pointer(msg)+nblock<<4, left)

        a = (a + 
            if isOver
                block[left+1] = 0x01
                little(reinterpret(UInt128, block)[])
            else
                little(reinterpret(UInt128, block)[]) + prefix
            end
        ) * r % p
    end

    return a::BigInt
end

function Poly1305MAC(msg::Array{Vector{UInt8}}, key::Vector{UInt8})
    r, s = reinterpret(UInt128, key)
    r = BigInt(little(r) & 0x0ffffffc0ffffffc0ffffffc0fffffff)
    s = BigInt(little(s))

    a = BigInt(0)
    for i in 1:length(msg)-1
        a = Poly1305Cal(r, a, msg[i], false)
    end
    a = Poly1305Cal(r, a, msg[end], true) + s

    return LeBytes(a, 16)::Array{UInt8}
end

function Poly1305MAC(msg::Vector{UInt8}, key::Vector{UInt8})
    r, s = reinterpret(UInt128, key)
    r = BigInt(little(r) & 0x0ffffffc0ffffffc0ffffffc0fffffff)
    s = BigInt(little(s))

    a = BigInt(0)
    a = Poly1305Cal(r, a, msg, true) + s

    return LeBytes(a, 16)::Array{UInt8}
end

end # module

找到几篇教你自定义类型的文章,你可以自己试着定义一个 UInt256 并实现相关操作符的运算:

谢谢你的回复,第一个定义了 MyInt8 类型,类似于 给 Int8 改个名,与我想要定义的 UInt256 不同,

第四个是 composite type,我不想使用长度为 2 的 Array{UInt128} 或

mutable struct UInt256
    upper::UInt128
    lower::UInt128
end

去定义 UInt256,

官方文档我也翻过几遍,没有介绍定义 primitive type,
第二个是操作符重载,和我想问的没有关系

虽然可以使用

primitive type UInt256 <: Unsigned 256 end

定义 UInt256,但不知道如何定义构造函数及怎么进行操作符重载

定义了类型后,肯定要定义运算