About 张 子萌

个人喜欢读书、上网、聊天。希望朋友之间多交流。
1月 28

golang用 channel简单高效队列

需求为先进先出原则,批量取出的缓存队列。要求比较简单,尝试开源queue代码,在压力大的情况下可能崩溃。使用redis做队列,CPU使用总量增长一倍多,IO开销也不小。最后用golang自带的channel,可以实现,简单高效,资源消耗也不大。

package main

import (
	"log"
	"os"
	"strconv"
	"time"
)

// 公共通道
// 通道数要比缓存最高数量大,以保证读取慢的情况下不会溢出
var Ch = make(chan string, 100000)

func wch(num int) {
	// 写入
	func() {
		if vv := recover(); vv != nil {
			os.Exit(0)
		}
	}()
	ws := strconv.Itoa(num)
	Ch <- ws
}

func rch() {
	// 读取
	var rs string
	for {
		select {
		case rs = <-Ch:
			log.Printf("read %v\n", rs)
		default:
			log.Printf("empty")
			return
		}
		if len(Ch) <= 0 {
			return
		}
		//Chsync.Done()
	}
}

func main() {
	var i int
	for i = 0; i < 200000; i++ {
		wch(i)
		if i%1000 == 0 {
			go rch()
			//Chsync.Add(1)
		}
	}
	time.Sleep(time.Millisecond * 6000)
	//Chsync.Wait()
	log.Printf("have %v", len(Ch))
}

12月 16

[转载]golang pprof

https://blog.wolfogre.com/posts/go-ppof-practice/

<code>_ "net/http/pprof" // 引入 pprof 模块
//  主函数内存分析
go func() {
	http.ListenAndServe("0.0.0.0:8090", nil)
}()</code>
<code>//命令行,收集cpu 如果生成svg 和图片安装 graphviz 
// top list 定位问题
go tool pprof http://localhost:8090/debug/pprof/profile
// 收集内存
go tool pprof http://localhost:8090/debug/pprof/heap
// 内存回收
go tool pprof http://localhost:8090/debug/pprof/allocs</code>
12月 02

esp32 +oled显示英文、中文

from machine import Pin, I2C
from oled import SSD1306_I2C
# 定义管脚
scl = Pin(22)
sda = Pin(21)
# 初始化
i2c = I2C(scl=scl, sda=sda)
# 像素 128*64
oled = SSD1306_I2C(128, 64, i2c)
# 清屏
oled.fill(0)
oled.show()

# 显示英文,从0,0像素开始
oled.text('hello', 0, 0)
oled.show()

# 以下为显示中文,重新显示需要清屏。fonts字体为自定义取模。
# 字索引为utf-8 16进制
# https://www.23bei.com/tool-217.html 在线取模
fonts= {
    # 你
    0xe4bda0:
[0x11,0x11,0x11,0x23,0x22,0x64,0xA8,0x20,0x21,0x21,0x22,0x24,0x20,0x20,0x21,0x20,
0x00,0x00,0x00,0xFC,0x04,0x08,0x40,0x40,0x50,0x48,0x4C,0x44,0x40,0x40,0x40,0x80],
    # 好
    0xe5a5bd:
[0x10,0x11,0x10,0x10,0xFC,0x24,0x24,0x27,0x24,0x44,0x28,0x10,0x28,0x44,0x84,0x00,
0x00,0xFC,0x04,0x08,0x10,0x20,0x24,0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40]
    }

def chinese(ch_str, x_axis, y_axis): 
   offset_ = 0 
   y_axis = y_axis*8  # 中文高  
   x_axis = (x_axis*16)  # 中文宽
   for k in ch_str:
       code = 0x00  # 中文转成16进制编码 
       data_code = k.encode("utf-8")
       code |= data_code[0] << 16 
       code |= data_code[1] << 8
       code |= data_code[2]
       byte_data = fonts[code]
       for y in range(0, 16):
           a_ = bin(byte_data[y]).replace('0b', '')
           while len(a_) < 8:
               a_ = '0'+a_
           b_ = bin(byte_data[y+16]).replace('0b', '')
           while len(b_) < 8:
               b_ = '0'+b_
           for x in range(0, 8):
               oled.pixel(x_axis+offset_+x, y+y_axis, int(a_[x]))   
               oled.pixel(x_axis+offset_+x+8, y+y_axis, int(b_[x]))   
       offset_ += 16
       
chinese('你好',0,0)
oled.show()
8月 31

rust学习初步

算法还是使用http://www.simonzhang.net/?p=2789。

study.rs

fn check(n:u64) -> bool{
    let ll = n.to_string().len();
    let cc = String::from(n.to_string());
    let mut nn1 = 0;
    let mut nn2 = ll-1;
    while nn1 < ll{
        if cc.chars().nth(nn1) != cc.chars().nth(nn2){
            return false;
        }
        if nn2 == 0{
            break;
        }
        nn1 += 1;
        nn2 -= 1;
    }
    return true;
}

fn main() {
    let x:u64 = 10;
    let y = x.pow(7);
    let mut i = 0;
    while i <= y {
        if check(i){
            if check(i*i){
                println!("{} {}", i, i*i)
            }
        }
        i+=1;
    }
}

cargo.toml

[profile.release]
lto = true
codegen-units = 1

使用UPX -9 压缩后400k,执行1秒以内。

6月 29

python3 多CPU加速

#!env python3
# -*- coding:utf-8 -*-
# Author:      simonzhang.net
import time
from multiprocessing import Pool

def toPrint(n):
    print(n, int(time.time()))
    time.slee(0.5)

if __name__=='__main__':
    # 系统有20个CPU
    p = Pool(20)
    # 加载数据
    for i in range(60):
        p.apply_async(toPrint, args=(i,))
    # 加载完成开始执行
    p.close()
    p.join()