关于头条人群包protobuf格式的php(python)解决方案

继上文: PHP使用protobuf

虽然php能序列化和反序列化,但是奈何头条不认啊,最后使用了python脚本的形式,去序列化,但很快就暴露出了问题,速度太慢!几万个设备号要序列化2小时+,当然主要的原因在于当时赶时间,是一个个设备号序列化的,大量的时间花在python上下文切换上,上文里的脚本能用,但是不适合稍微量大一点的场景,故而用三脚猫的功夫写了一个新的python脚本,接受文件,吐出序列化后的新文件,速度大大提升,实测大概1000/s个设备号。

from __future__ import print_function
import DmpDataProtoV2_pb2
import os,sys
import time
import base64


ag_len = sys.argv.__len__()
if ag_len <= 1:
    print ('ag is null')
    exit()
file = sys.argv[1]
if not file.strip():
    print ('files is null')
    exit()
if not os.path.exists(file):
    print ('files is not exists')
    exit()
f = open(file)

line = f.readline()
line=line.strip('\n')
base_name = os.path.splitext(file)[0]
target_file = base_name + '-ProtoBuf.txt'
print(target_file)
# if os.path.exists(target_file)::
#     os.remove(target_file)
t = open(target_file, 'w')
t.truncate()
while line:
    line=line.strip('\n')
    if not line.strip():
        continue
    arr = line.split('|')
    if arr.__len__() != 2:
        continue
    dmp_data  = DmpDataProtoV2_pb2.DmpData()
    id_item1  = dmp_data.idList.add()
    dtype     = arr[0]
    dev_id    = arr[1]
    id_item1.dataType = getattr(DmpDataProtoV2_pb2.IdItem,dtype)
    #id_item1.dataType = DmpDataProtoV2_pb2.IdItem.IDFA
    id_item1.id = str.lower(dev_id)
    id_item1.tags.append(dtype)
    # id_item1.timestamp = int(time.time())

    binary_string  = dmp_data.SerializeToString()
    s = base64.b64encode(binary_string)
    t.write(s+"\n");
    line = f.readline()
    line=line.strip('\n')
f.close()

PHP调用部分

//从py重写
$protobuf_path = shell_exec("python ".base_path()."/scripts/python/base64DmpItemByFile.py {$file_path}");

Done!

你可能感兴趣的:(protobuf,php)