Projection 最近回复了
创建一个类并自定义 __contains__ 魔术方法,实现则使用 bisect 二分查找。根据这个思路找 GPT 生成了代码:
import bisect
class OrderedList:
def __init__(self, items):
# 确保列表有序
self.items = sorted(items)
# 自定义 in 操作,使用二分查找
def __contains__(self, item):
# 使用 bisect 模块进行二分查找
index = bisect.bisect_left(self.items, item)
# 检查查找到的索引是否在范围内,且对应元素是否与目标相等
return index < len(self.items) and self.items[index] == item
# 支持遍历
def __iter__(self):
return iter(self.items)
# 使用示例
ordered_list = OrderedList([10, 1, 7, 3, 5])
# 遍历
for item in ordered_list:
print(item) # 输出: 1 3 5 7 10 (有序)
# 使用自定义的 in 操作(使用二分查找)
print(7 in ordered_list) # 输出: True
print(6 in ordered_list) # 输出: False
原来是分组的 Base36 ,我还以为是常规的 Base36 ,然后优化内存使用
我想明白你怎么算的了:
```python
import math
for m in range(1, 16):
n = math.ceil(math.log(256 ** m, 36))
ratio = m / n
print(f'{m=} bytes, {n=} chars, {ratio=:.2%}')
```
m=1 bytes, n=2 chars, ratio=50.00%
m=2 bytes, n=4 chars, ratio=50.00%
m=3 bytes, n=5 chars, ratio=60.00%
m=4 bytes, n=7 chars, ratio=57.14%
m=5 bytes, n=8 chars, ratio=62.50%
m=6 bytes, n=10 chars, ratio=60.00%
m=7 bytes, n=11 chars, ratio=63.64%
m=8 bytes, n=13 chars, ratio=61.54%
m=9 bytes, n=14 chars, ratio=64.29%
m=10 bytes, n=16 chars, ratio=62.50%
m=11 bytes, n=18 chars, ratio=61.11%
m=12 bytes, n=19 chars, ratio=63.16%
m=13 bytes, n=21 chars, ratio=61.90%
m=14 bytes, n=22 chars, ratio=63.64%
m=15 bytes, n=24 chars, ratio=62.50%
@
iqoo 任何程序编码出来结果都是一样的,和空间利用率有什么关系
没有搞懂你说的空间利用率是什么意思。
假设我每次只读取一个字节的数据而不是 9 字节,那么刚开始会产生一个字符,照你的说法空间利用率不就是 100% 了?
每次读取 9 字节只能保证至少产生 13 个字符(比如刚开始时),有时才会产生 14 个字符。当产生 13 个字符时,你说的空间利用率就是 9 / 13 = 0.69 了。
>>> 36 ** 13 < 256 ** 9 < 36 ** 14
True
你可能是想要找到一个缓存区的大小 m ,满足 `256 ** m >= 36 ** n` 且左右两边占用 bits 差值足够小,但是概念上没有理清。我倒是觉得应该这样算:
```python
import math
base = 36
for m in range(1, 16):
n = int(math.log(256 ** m, 36))
waste = m * 8 - math.log2(36 ** n)
print(f'{m=} bytes, {n=} chars, {waste=} bits')
```
m=1 bytes, n=1 chars, waste=2.830074998557688 bits
m=2 bytes, n=3 chars, waste=0.49022499567306355 bits
m=3 bytes, n=4 chars, waste=3.3202999942307514 bits
m=4 bytes, n=6 chars, waste=0.9804499913461271 bits
m=5 bytes, n=7 chars, waste=3.8105249899038114 bits
m=6 bytes, n=9 chars, waste=1.470674987019187 bits
m=7 bytes, n=10 chars, waste=4.3007499855768785 bits
m=8 bytes, n=12 chars, waste=1.9608999826922542 bits
m=9 bytes, n=13 chars, waste=4.790974981249946 bits
m=10 bytes, n=15 chars, waste=2.451124978365314 bits
m=11 bytes, n=17 chars, waste=0.11127497548069698 bits
m=12 bytes, n=18 chars, waste=2.941349974038374 bits
m=13 bytes, n=20 chars, waste=0.601499971153757 bits
m=14 bytes, n=21 chars, waste=3.431574969711434 bits
m=15 bytes, n=23 chars, waste=1.091724966826817 bits
很明显 9 字节的空间利用率非常低。即便如此浪费的也是几个 bits 而已,在字节这个粒度下感觉空间利用率就是个伪需求。
requestDelay() 前面要加 await 才行,不然你这样就是开启 10 个请求,后面 requestInstant() 只能排队
你说的这个用 Streams API 很容易实现:
```js
import { setTimeout } from "node:timers/promises";
let id = 0;
async function fetchData() {
console.log("fetchData()");
await setTimeout(Math.random() * 500);
return Array(10)
.fill(null)
.map(() => ({ id: ++id }));
}
const stream = new ReadableStream(
{
async pull(controller) {
const data = await fetchData();
for (const a of data) {
controller.enqueue(a);
}
},
},
new CountQueuingStrategy({ highWaterMark: 0 }), // fully lazy
).values();
async function getD() {
return (await stream.next()).value;
}
for (let i = 0; i < 30; i++) {
console.log("data", await getD());
}
```
输出结果:
fetchData()
data { id: 1 }
data { id: 2 }
data { id: 3 }
data { id: 4 }
data { id: 5 }
data { id: 6 }
data { id: 7 }
data { id: 8 }
data { id: 9 }
data { id: 10 }
fetchData()
data { id: 11 }
data { id: 12 }
data { id: 13 }
data { id: 14 }
data { id: 15 }
data { id: 16 }
data { id: 17 }
data { id: 18 }
data { id: 19 }
data { id: 20 }
fetchData()
data { id: 21 }
data { id: 22 }
data { id: 23 }
data { id: 24 }
data { id: 25 }
data { id: 26 }
data { id: 27 }
data { id: 28 }
data { id: 29 }
data { id: 30 }
这里为了定义你所需要 getD() 显得把代码搞复杂了一点,而实际上你可以根据情况使用 for await... of 。
你从 LLM 获得的代码有轮询的部分,所以强烈不推荐:
await new Promise(resolve => setTimeout(resolve, 100)); // 等待数据获取完成