2016-03-13 4 views
2

Я использую strings.Split, чтобы разделить строку.Как преобразовать срез в строку в golang?

Я хочу, чтобы моя программа сохраняла один из элементов массива и освобождала базовый массив.

К сожалению, я не могу понять, как преобразовать срез строки в строку, которая не относится к базовой строке.

Я должен сделать что-то вроде этого:

func unslice(s string) (string) { 
    return string([]byte(s)) 
} 

Предпосылка:

  1. основная строка очень большой
  2. срез Я хочу сохранить очень мало
  3. ломтик, который я хочу сохранить, будет сохранен в течение длительного времени
  4. программа будет работать для долгое время - несколько недель или более
  5. во время работы программы будет разделить многие из этих строк (миллионы)

Вот пример в ответ на комментарий.

func takesBigStringOften(big string) { 
    parts := strings.Split(big, " ") 

    saveTinyStringForALongTime(parts[0]) 
} 
+0

Неужели поставленный гол не работает так, как вы хотите? –

+0

Какая цель? Приведите пример. – XXXX

+0

@MuffinTop Я не уверен, что он делает то, что я хочу. Я также не уверен, есть ли стандартный способ сделать это. Я полагаю, что это очень распространенная вещь, поэтому я был удивлен, что я не смог найти ничего из-за googling. – Coder

ответ

2

Для того, чтобы Go не сохраняет основную строку в памяти вы должны явно скопировать его на новое место:

func unslice(old string) string { 
    new := make([]byte,len(old)) 
    copy(new,old) 
    return string(old) 
} 

SmallString := unslice(BigString[0:7]) 
+0

Спасибо, это означает, что в моем попытке решение '[] byte (s)' возвращает срез? – Coder

+0

@Coder yes '[] byte (s)' возвращает байтовый срез, где каждый байт является одним символом из строки 's'. – evanmcdonnal

+0

@evanmcdonnal спасибо! – Coder

2

Просто как-то дополнительной информации. Некоторые контрольные показатели и профилирование памяти показывают, что с точки зрения 1.5.3 оба метода выделяют один и тот же объем памяти из кучи, т. Е. Новая копия делается в любом случае. При построении строки из байтового фрагмента компилятор вызывает процедуру, которая создает уникальную копию байтов - поскольку строки неизменяемы, а байтовые фрагменты - нет.

$ go tool pprof -alloc_space so002.test cprof0 
Entering interactive mode (type "help" for commands) 
(pprof) list copy 
Total: 9.66MB 
    9.62MB  9.62MB (flat, cum) 99.55% of Total 
     .   .  15: 
     .   .  16:var global string 
     .   .  17: 
     .   .  18:func benchmarkcopy(b *testing.B, c int) { 
     .   .  19: big := "This is a long string" 
     .  240B  20: parts := strings.Split(big, " ") 
     .   .  21: old := parts[0] 
     .   .  22: jlimit := 100 
     .   .  23: for i := 0; i < b.N; i++ { 
     .   .  24:  for j := 0; j < jlimit; j++ { 
    3.21MB  3.21MB  25:   global = string([]byte(old)) 
     .   .  26:  } 
     .   .  27:  for j := 0; j < jlimit; j++ { 
     .   .  28:   b := []byte(old) 
    3.21MB  3.21MB  29:   global = string(b) 
     .   .  30:  } 
     .   .  31:  for j := 0; j < jlimit; j++ { 
    3.21MB  3.21MB  32:   new := make([]byte, len(old)) 
     .   .  33:   copy(new, old) 
     .   .  34:   global = string(old) 
     .   .  35:  } 
     .   .  36: } 
     .   .  37:} 
+0

Ницца! В этом есть смысл. Очень тщательный ответ. Я не знал об профилировании – Coder

+0

Так много вещей, чтобы полюбоваться идеей. Одним из них является простой cpu и профилирование памяти. Я все еще пытаюсь упорядочить свою собственную настройку профилирования, поэтому мне легко профайл, который меня волнует. Я вижу других, кто лучше разбирается в этом и, кажется, воспринимает это как должное. Все еще пытаясь добраться до такого уровня комфорта, поэтому вопрос здесь казался идеальным для небольшого эксперимента. – WeakPointer

Смежные вопросы