小编gmo*_*oss的帖子

marisa trie后缀压缩?

我正在使用这个marisa trie库的自定义Cython包装器作为键值多图.

我的trie条目看起来像key 0xff data1 0xff data2映射key到元组(data1, data2).data1是一个可变长度的字符串,但data2始终是一个4字节的无符号整数.这0xff是一个分隔符字节.

从理论角度来看,我知道trie不是最优化的数据结构,但是各种实际考虑因素使其成为最佳选择.

在这个用例中,我有大约1000万到2000万个密钥,每个密钥平均有10个数据点.data2对于许多条目来说是多余的(在某些情况下,data2给定密钥的所有数据点总是相同的),所以我想到了最频繁的data2输入并("", base_data2)为每个密钥添加了一个数据点.

由于MARISA trie,据我所知,没有后缀压缩,并且对于给定的密钥,每个data1都是唯一的,我假设这将为使用冗余密钥的每个数据元组节省4个字节(加上添加一个4字节的"值") "为每把钥匙).重建了trie后,我检查了冗余数据不再存储.我预计序列化和内存大小都会大幅减少,但实际上磁盘上的trie从566MB增加到557MB(并且加载的trie的RAM使用量也有类似的减少).

由此我得出结论,没有后缀压缩我一定是错的.我现在用多余的data2数字存储条目key 0xff data1 0xff,所以为了测试这个理论,我删除了尾随0xff并调整了使用trie处理的代码.新的trie从557MB下降到535MB.

因此,删除单个冗余尾随字节比删除相同数量的4字节序列提高了2 倍,因此后缀压缩理论是错误的,或者它以某种非常复杂的方式实现.

我剩下的理论是,在("", base_data2)trie中更高点添加条目会以某种可怕的方式抛出压缩,但是当我从中删除多于下来时,它应该只增加4个字节.线索.

我对修复并不乐观,但我非常想知道为什么我会看到这种行为!感谢您的关注.

c++ python trie

10
推荐指数
1
解决办法
415
查看次数

python的`timeit`并不总是与数字线性对比?

我在16GB,2.7GHz i5,OSX 10.11.5机器上运行Python 2.7.10.

我在许多不同类型的例子中多次观察到这种现象,所以下面的例子虽然有点人为,但具有代表性.这正是我今天早些时候正在努力的事情,当我的好奇心终于被激起时.

>>> timeit('unicodedata.category(chr)', setup = 'import unicodedata, random; chr=unichr(random.randint(0,50000))', number=100)
3.790855407714844e-05
>>> timeit('unicodedata.category(chr)', setup = 'import unicodedata, random; chr=unichr(random.randint(0,50000))', number=1000)
0.0003371238708496094
>>> timeit('unicodedata.category(chr)', setup = 'import unicodedata, random; chr=unichr(random.randint(0,50000))', number=10000)
0.014712810516357422
>>> timeit('unicodedata.category(chr)', setup = 'import unicodedata, random; chr=unichr(random.randint(0,50000))', number=100000)
0.029777050018310547
>>> timeit('unicodedata.category(chr)', setup = 'import unicodedata, random; chr=unichr(random.randint(0,50000))', number=1000000)
0.21139287948608398
Run Code Online (Sandbox Code Playgroud)

您会注意到,从100到1000,正如预期的那样,时间增加了10倍.然而,1e3到1e4,它更像是因子50,然后是从1e4到1e5的因子2(所以从1e3到1e5的总因数为100,这是预期的).

我认为必须在实际的过程中进行某种基于缓存的优化,无论是在实际的过程中还是在timeit本身,但我不能完全根据经验弄清楚是否是这种情况.进口似乎并不重要,可以通过一个最基本的例子来观察:

>>> timeit('1==1', number=10000)
0.0005490779876708984
>>> timeit('1==1', number=100000)
0.01579904556274414
>>> timeit('1==1', number=1000000)
0.04653501510620117
Run Code Online (Sandbox Code Playgroud)

从1e4到1e6,存在1e2时差的真实因子,但中间步长为~30和~3.

我可以做更多临时数据收集,但此时我还没有考虑过假设.

关于为什么非线性标度在某些中间运行次数的任何概念?

python optimization performance timeit

9
推荐指数
1
解决办法
194
查看次数

在同一线程中使用两个 sqlalchemy 连接器时 mysql 连接丢失

用例和背景:

我想SELECT GET_LOCK针对固定副本使用,因此我的所有服务器都可以看到针对我的数据子集的相同锁,但将针对 mysql 的负载分配给多个副本,以便我的服务器可以在数据的不同子集上工作数据。因此我有mysql_connector_locksmysql_connector_data

其中每个connector对象都是 sqlalchemy 引擎和 sessionmaker 的包装器。他们每个人都有

def get_mysql_session(self, isolation_level=None):
    if not self.session_maker:
        self.session_maker = sessionmaker()
        self.session_maker.configure(bind=self.engine)
    session = self.session_maker()
    if isolation_level is not None:
        session.connection(execution_options={'isolation_level': isolation_level.value})
    try:
        yield session
        session.commit()
    except Exception:
        session.rollback()
        raise
    finally:
        session.close()
Run Code Online (Sandbox Code Playgroud)

现在,我有了我的代码

for data_subset_id in partitioned_data:
    with mysql_connector_locks.get_mysql_session() as session_locks:
        try:
            with get_lock(session_locks, data_subset_id):
                with mysql_connector_data.get_mysql_session(
                    isolation_level=IsolationLevel.READ_UNCOMMITTED
                ) as session_data:
                    data = get_data(session_data, data_subset_id)
                    process_data(data)
        except LockNotAcquired:
            continue
Run Code Online (Sandbox Code Playgroud)

其中get_lock遵循获取锁的标准方法。

出了什么问题:

每个服务器都会经历一次循环迭代,获取第二次迭代的锁,并在调用 …

mysql sqlalchemy

9
推荐指数
0
解决办法
150
查看次数

在py3中使用nltk时出现“错误转义”

NLTK版本3.4.5。Python 3.7.4。OSX版本10.14.5。

从2.7升级代码库,刚开始遇到此问题。我已经在全新的virtualenv中完成了所有软件包和扩展的全新无缓存重新安装。关于这怎么可能只发生在我身上,我很迷惑,我找不到其他在线遇到相同错误的人。

(venv3) gmoss$ python
Python 3.7.4 (default, Sep  7 2019, 18:27:02) 
[Clang 10.0.1 (clang-1001.0.46.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import nltk
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/gmoss/Documents/constructor/autocomplete/venv3/lib/python3.7/site-packages/nltk/__init__.py", line 150, in <module>
    from nltk.translate import *
  File "/Users/gmoss/Documents/constructor/autocomplete/venv3/lib/python3.7/site-packages/nltk/translate/__init__.py", line 23, in <module>
    from nltk.translate.meteor_score import meteor_score as meteor
  File "/Users/gmoss/Documents/constructor/autocomplete/venv3/lib/python3.7/site-packages/nltk/translate/meteor_score.py", line 10, in <module>
    from nltk.stem.porter import PorterStemmer
  File "/Users/gmoss/Documents/constructor/autocomplete/venv3/lib/python3.7/site-packages/nltk/stem/__init__.py", line 29, in <module>
    from …
Run Code Online (Sandbox Code Playgroud)

python nltk python-3.x

8
推荐指数
1
解决办法
53
查看次数

Python内存泄漏,类中的加载属性未被收集

我使用的是python 2.7.14.可以在OSX和Linux上重现.

我有一些python类:

import cPickle

class TestClass:
    def __init__(self, path_to_data=None):
        self.loaded_data = None
        if path_to_data:
            self.load(path_to_data)

    def load(self, path_to_data):
        self.loaded_data = None
        with open(path_to_data, 'r') as f:
            self.loaded_data = cPickle.load(f)
Run Code Online (Sandbox Code Playgroud)

你可以制作一个体面的腌制词典:

>>> import cPickle
>>> d = {x:x+1 for x in range(1000000)}
>>> with open('testdict.pkl', 'w+') as f:
>>>     cPickle.dump(d, f)
Run Code Online (Sandbox Code Playgroud)

并重复这样的问题:

>>> from test_py import TestClass
>>> import psutil
>>> import os
>>> process = psutil.Process(os.getpid())
>>> process.memory_info()
pmem(rss=8085504L, vms=4405288960L, pfaults=2154, pageins=0)
>>>
>>> t = TestClass('testdict.pkl')
>>> process.memory_info() …
Run Code Online (Sandbox Code Playgroud)

python memory-leaks python-2.7

5
推荐指数
0
解决办法
163
查看次数

组成 itemgetter 和 attrgetter 的 pythonic 方式?

我有一些代码要移植到 Cython,其中有一行类似

my_list.sort(key=lambda x: x.attr[item])
Run Code Online (Sandbox Code Playgroud)

有没有一种很好的Pythonic方法来避免使用itemgetter和attrgetter的某种组合来关闭?

python closures cython

3
推荐指数
1
解决办法
1064
查看次数

内部使用`cons`适用于mapcar

在Lisp Koans中,此处使用以下形式来转置矩阵:

(defun transpose (L) (apply #'mapcar (cons #'list L)))

当我解析此函数时,(cons #'list L)返回一个列表'(#'list L1 L2 L3 ...)L_i矩阵的列在哪里L。然后apply展开该列表,现在mapcar list将as的列作为其参数L,从而构造的行L

我想知道是否有任何原因,除了强迫一个新的Lisp学生记住并理解的用法的教学论之外cons,还不只是写

(defun transpose (L) (apply #'mapcar #'list L))

因为L已经是一个列表(以列(作为列表)),所以在拆包之前,这些列表apply#'list位于列表中L

可以再简化一下吗?我认为apply,为了将参数解包以便用于mapcar从行中创建列表是必须的,但是我对函数式编程是陌生的。

谢谢!

common-lisp

2
推荐指数
1
解决办法
33
查看次数